Пример #1
0
        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;
        }
Пример #2
0
 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);
     }
 }
Пример #3
0
 public TvDataView(Tv p_owner, ITreeData p_data)
 {
     _owner = p_owner;
     _data  = p_data;
     //if (_data is INotifyCollectionChanged coll)
     //    coll.CollectionChanged += OnDataCollectionChanged;
     Refresh();
 }
Пример #4
0
        private void TreePanel_MouseClick(object sender, MouseEventArgs e)
        {
            ITreeData node = findPersonFromPoint(e.X, e.Y);

            if (node != null)
            {
                OnNodeClick?.Invoke(this, node);
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        private void TreePanel1_OnNodeDoubleClick(object sender, ITreeData node)
        {
            var pnode = node as PersonNode;

            if (pnode == null)
            {
                return;
            }
            SelectPerson(pnode.Who);
        }
Пример #7
0
        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?
        }
Пример #8
0
        // 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);
        }
Пример #9
0
 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);
     //}
 }
Пример #10
0
 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);
 }
Пример #11
0
 private void MarkForHighlight(ITreeData node)
 {
     if (node == null)
     {
         if (lightNode != null)
         {
             lightNode = null;
             Refresh();
         }
     }
     else
     {
         lightNode = node;
         Refresh();
     }
 }
Пример #12
0
        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);
            }
        }
Пример #13
0
        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);
            }
        }
Пример #14
0
        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);
                    }
                }
            }
        }
Пример #15
0
 public void SetData(ITreeData value)
 {
     data = value as ExplorerObjectData;
 }
Пример #16
0
 public void SetData(ITreeData value)
 {
     data = value as ExplorerFunctionData;
 }
Пример #17
0
 public void SetData(ITreeData value)
 {
     data = value as ExplorerGraphData;
 }
Пример #18
0
        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));
                }
            }
        }
Пример #19
0
 private Rect getBoundsOfNode(ITreeData node)
 {
     return(_boxen.getNodeBounds()[node]);
 }
Пример #20
0
        private Rectangle drawBounds(ITreeData node)
        {
            Rect r = getBoundsOfNode(node);

            return(new Rectangle((int)r.Left, (int)r.Top, (int)r.Width, (int)r.Height));
        }
Пример #21
0
        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;
        }
Пример #22
0
 private IEnumerable <ITreeData> getChildren(ITreeData parent)
 {
     return(GetTree().getChildren(parent));
 }
Пример #23
0
 public TreeController(ITreeData treeData)
 {
     _treeData = treeData;
 }
Пример #24
0
 public void SetData(ITreeData value)
 {
     data = value as ExplorerVariableData;
 }
Пример #25
0
        private bool hasChildren(ITreeData parent)
        {
            var enumer = getChildren(parent);

            return(enumer != null && enumer.Any());
        }
Пример #26
0
        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);
        }
Пример #27
0
 TeeNodeCompareResult TreeCompare(ITreeData child, ITreeData parent)
 {
     return(child.TreeDataComPare(parent));
 }
Пример #28
0
 public void SetData(ITreeData value)
 {
     data = value as ExplorerPropertyData;
 }