private static void GrowTree(ITreeData parent, Union marr) { _genDepth = _genDepth + 1; // In the multi-marriage situation, we need to add // the children of a *specific* marriage as child-nodes // of the parent. foreach (var child in marr.Childs) { switch (child.SpouseIn.Count) { case 0: case 1: ITreeData node = MakeNode(child, _genDepth); _tree.addChild(parent, node); GrowTree(node as UnionNode); break; default: MultiMarriage(parent, child, _genDepth); break; } } _genDepth = _genDepth - 1; }
private void PaintEdges(ITreeData parent) { if (parent is PersonNode) { var p = parent as PersonNode; // Don't draw the fake for multi-marriage at root if (!string.IsNullOrEmpty(p.Text) || p.Who != null) { paintPersonEdges(parent as PersonNode); } } else { if (parent.Vertical) { paintUnionEdgesV(parent as UnionNode); } else { paintUnionEdgesH(parent as UnionNode); } } foreach (var child in getChildren(parent)) { PaintEdges(child); } }
public TvDataView(Tv p_owner, ITreeData p_data) { _owner = p_owner; _data = p_data; //if (_data is INotifyCollectionChanged coll) // coll.CollectionChanged += OnDataCollectionChanged; Refresh(); }
private void TreePanel_MouseClick(object sender, MouseEventArgs e) { ITreeData node = findPersonFromPoint(e.X, e.Y); if (node != null) { OnNodeClick?.Invoke(this, node); } }
public ITreeData Create(ITreeData p1, ITreeData p2, string unionId) { var p1A = (PersonNode)p1; var p2A = (PersonNode)p2; var node = new UnionNode(p1A, p2A, unionId, _vertOrient); p1A.IsReal = p1A.DrawVert; // TODO brother/sister incest: both spouses are children p2A.IsReal = p2A.DrawVert; return(node); }
private void TreePanel1_OnNodeDoubleClick(object sender, ITreeData node) { var pnode = node as PersonNode; if (pnode == null) { return; } SelectPerson(pnode.Who); }
private void TreePanel1_OnNodeClick(object sender, ITreeData node) { var pnode = node as PersonNode; if (pnode == null) { return; } // TODO what do we want to do on single-click? }
// TODO should be in tree classes? private ITreeData findPersonFromPoint(int X, int Y) { ITreeData node = findNodeByPoint(X - 8, Y - 8); // TODO WHY is this delta necessary? UnionNode un = node as UnionNode; if (un != null) { node = getPersonFromUnion(un, X - 8, Y - 8); } return(node); }
private void TreePanel1_OnNodeHover(object sender, ITreeData node) { var pnode = node as PersonNode; //if (pnode == null) //{ // toolTip1.Hide(treePanel1); //} //else //{ // toolTip1.Show(pnode.Text, treePanel1); //} }
public void AddSpouse(ITreeData node) { // In the multi-marriage situation, the child // has been created as a PersonNode, and each // spouse as "not real" PersonNodes. To be able // to draw the appropriate edge(s) from the // child to each spouse, track them here. if (_multSpouses == null) { _multSpouses = new List <ITreeData>(); } _multSpouses.Add(node); }
private void MarkForHighlight(ITreeData node) { if (node == null) { if (lightNode != null) { lightNode = null; Refresh(); } } else { lightNode = node; Refresh(); } }
private void DrawChildrenEdgesH(ITreeData parent, int startx, int starty) { // Common code to draw edges from parent-node to children-nodes. // Horizontal (root at top) variant. // Used for UnionNode parent, and PersonNode parent in the multi-marriage // scenario. // Start position: place to start whether a union or a person node var b1 = drawBounds(parent); // Bottom point - vertical line from start position to child line int targetY = b1.Bottom + (gapBetweenLevels / 2); // Vertical connector from start position to child-line _g.DrawLine(_childPen, startx, starty, startx, targetY); // determine the left/right of the child-line int minChildX = int.MaxValue; int maxChildX = int.MinValue; foreach (var child in getChildren(parent)) { // Do not draw 'I'm a child' line for spouses if (child is PersonNode && !((PersonNode)child).DrawVert) { continue; } var b2 = drawBounds(child); int childX = b2.Left + child.ParentConnectLoc; int childY = b2.Top; minChildX = Math.Min(minChildX, childX); maxChildX = Math.Max(maxChildX, childX); // vertical line from top of child to half-way up to previous level _g.DrawLine(_childPen, childX, childY, childX, targetY); } _g.DrawLine(_childPen, minChildX, targetY, maxChildX, targetY); // Union has a single child. Vertical from child unlikely to // connect to vertical from union. Draw a horizontal connector. if (minChildX == maxChildX) { _g.DrawLine(_childPen, minChildX, targetY, startx, targetY); } }
private void TreePanel_MouseMove(object sender, MouseEventArgs e) { if (Math.Abs(lastX - e.X) < 3 && Math.Abs(lastY - e.Y) < 3) // ignore minor move delta { return; } lastX = e.X; lastY = e.Y; ITreeData node = findPersonFromPoint(e.X, e.Y); MarkForHighlight(node); if (node != null) { OnNodeHover?.Invoke(this, node); } }
private static void MultiMarriage(ITreeData parent, Person who, int depth) { // A person has multiple marriages. // 1. Make the person a child of the parent. // 2. For each marriage: // 2a. Add the spouse as a not-real child of the parent. // 2b. Connect each spouse to the person for drawing. // 2c. call GrowTree(spouse, marriage) PersonNode nodeP = (PersonNode)_nf.Create(who, StringForNode(who), ColorForNode(who), depth); _tree.addChild(parent, nodeP); foreach (var marr in who.SpouseIn) { // Add each spouse as a pseudo-child of the 'parent' Person spouseP = marr.Spouse(who); PersonNode node = (PersonNode)_nf.Create(spouseP, StringForNode(spouseP), ColorForNode(spouseP), depth, true); node.IsReal = false; nodeP.AddSpouse(node); _tree.addChild(parent, node); // This union might have already been added to the // tree. If so, provide a link to the previous node, // and do NOT add children. ITreeData dup; if (_unionSet.TryGetValue(marr.Id, out dup)) { nodeP.DupNode = dup; node.DupNode = dup; } else { _unionSet.Add(marr.Id, nodeP); // here we're about to start the next level, punt if limit reached if (_genDepth < _config.MaxDepth) { GrowTree(node, marr); } } } }
public void SetData(ITreeData value) { data = value as ExplorerObjectData; }
public void SetData(ITreeData value) { data = value as ExplorerFunctionData; }
public void SetData(ITreeData value) { data = value as ExplorerGraphData; }
private void paintNode(ITreeData node) { int currDepth = 0; int genLineY = 0; bool drawVert = false; Rectangle box = drawBounds(node); PersonNode foo = node as PersonNode; if (foo != null) { // Don't draw the fake for multi-marriage at root if (foo.Text != " " || foo.Who != null) { paintABox(foo, box); } currDepth = foo.Depth; genLineY = foo.Vertical ? box.Right : box.Bottom; drawVert = foo.Vertical; } else { // Drawing a union node. Said node consists of two Person boxes. // (Spouse connector drawn in PaintEdges). UnionNode bar = node as UnionNode; if (bar != null) { Rectangle box1 = new Rectangle(box.X, box.Y, bar.P1.Wide, bar.P1.High); Rectangle box2; if (bar.Vertical) { box2 = new Rectangle(box.X, box.Y + bar.P1.High + UNION_BAR_WIDE, bar.P2.Wide, bar.P2.High); } else { box2 = new Rectangle(box.X + bar.P1.Wide + UNION_BAR_WIDE, box.Y, bar.P2.Wide, bar.P2.High); } paintABox(bar.P1, box1); paintABox(bar.P2, box2); currDepth = bar.P1.Depth; genLineY = bar.Vertical ? Math.Max(box1.Right, box2.Right) : Math.Max(box1.Bottom, box2.Bottom); drawVert = bar.Vertical; } // debugging //using (var pen = new Pen(Color.Magenta)) // _g.DrawRectangle(pen, box); } if (currDepth == _nextLevel && _config.GenLines) { _nextLevel += 1; genLineY += 8; if (drawVert) { _g.DrawLine(Pens.Blue, new Point(genLineY, 0), new Point(genLineY, Height)); } else { _g.DrawLine(Pens.Blue, new Point(0, genLineY), new Point(Width, genLineY)); } } }
private Rect getBoundsOfNode(ITreeData node) { return(_boxen.getNodeBounds()[node]); }
private Rectangle drawBounds(ITreeData node) { Rect r = getBoundsOfNode(node); return(new Rectangle((int)r.Left, (int)r.Top, (int)r.Width, (int)r.Height)); }
private static void GrowTree(UnionNode parent) { if (parent == null) { return; // person has no spouse/child } var who = parent.P1.Who ?? parent.P2.Who; if (who == null) // both parents empty, shouldn't get here! { return; } // This union might have already been added to the // tree. If so, provide a link to the previous node, // and do NOT add children. ITreeData dup; if (_unionSet.TryGetValue(parent.UnionId, out dup)) { parent.DupNode = dup; return; } _unionSet.Add(parent.UnionId, parent); // About to start the next layer down the tree. punt if we've hit the limit if (_genDepth >= _config.MaxDepth) { return; } _genDepth = _genDepth + 1; // 20200407 - when selecting the 2d spouse of a multi-marriage, need // to get the correct union. Union marr = who.SpouseIn.Where(x => x.Id == parent.UnionId).FirstOrDefault(); if (marr == null) // shouldn't happen { return; } foreach (var child in marr.Childs) { switch (child.SpouseIn.Count) { case 0: case 1: ITreeData node = MakeNode(child, _genDepth); _tree.addChild(parent, node); GrowTree(node as UnionNode); break; default: MultiMarriage(parent, child, _genDepth); break; } } _genDepth = _genDepth - 1; }
private IEnumerable <ITreeData> getChildren(ITreeData parent) { return(GetTree().getChildren(parent)); }
public TreeController(ITreeData treeData) { _treeData = treeData; }
public void SetData(ITreeData value) { data = value as ExplorerVariableData; }
private bool hasChildren(ITreeData parent) { var enumer = getChildren(parent); return(enumer != null && enumer.Any()); }
private void DrawChildrenEdgesV(ITreeData parent) { var b1 = drawBounds(parent); // Line from left side of children to half way across the gen. gap // This *only* works if alignment for nodes is "toward root"! // [because with align==center, narrow children are further right, i.e. // the 'left side of children' is not constant]. // 20180818 In theory, getSizeOfLevel could work for calculating this, except // we need to be able to determine a node's level, which doesn't work // right now for 'pseudo' nodes. // e.g. double levelWide = _boxen.getSizeOfLevel(_boxen.getLevelForNode(parent)) int targetX = -1; int startY = b1.Top + b1.Height / 2; // Determine the top/bottom of the child-line int minChildY = int.MaxValue; int maxChildY = int.MinValue; foreach (var child in getChildren(parent)) { // Do not draw 'I'm a child' line for spouses if (child is PersonNode && !((PersonNode)child).DrawVert) { continue; } var b2 = drawBounds(child); // Determine the location of the child line relative to the // child left side [requires align == towardroot!] if (targetX == -1) { targetX = b2.Left - gapBetweenLevels / 2; } int childX = b2.Left; int childY = b2.Top + child.ParentConnectLoc; minChildY = Math.Min(minChildY, childY); maxChildY = Math.Max(maxChildY, childY); _g.DrawLine(_childPen, targetX, childY, childX, childY); } // In the case a union has a single child, the horz. from child unlikely to // connect to horz. from union. Draw a vert. connector. if (minChildY == maxChildY) { _g.DrawLine(_childPen, targetX, minChildY, targetX, startY); } else { _g.DrawLine(_childPen, targetX, minChildY, targetX, maxChildY); } // TargetX has been calculated, can draw from the parent to the // child line. _g.DrawLine(_childPen, b1.Right, startY, targetX, startY); }
TeeNodeCompareResult TreeCompare(ITreeData child, ITreeData parent) { return(child.TreeDataComPare(parent)); }
public void SetData(ITreeData value) { data = value as ExplorerPropertyData; }