Exemplo n.º 1
0
 /// <summary>
 /// Helper function that indicates if given collection is the root.
 /// </summary>
 /// <param name="tc">Reference to owning TreeControl.</param>
 /// <param name="nc">Reference to NodeCollection instance.</param>
 /// <returns></returns>
 public virtual bool IsRootCollection(TreeControl tc, NodeCollection nc)
 {
     return(tc.Nodes == nc);
 }
Exemplo n.º 2
0
 /// <summary>
 /// Process a left mouse down on the Node instance.
 /// </summary>
 /// <param name="tc">Reference to owning TreeControl.</param>
 /// <param name="nc">Reference to NodeCollection instance.</param>
 /// <param name="n">Reference to Node within collection.</param>
 /// <param name="pt">Point being pressed down.</param>
 /// <returns>true if the point was processed; otherwise false.</returns>
 public virtual bool DoubleClick(TreeControl tc, NodeCollection nc, Node n, Point pt)
 {
     // Not processed
     return(false);
 }
Exemplo n.º 3
0
        /// <summary>
        /// Draw the NodeCollection instance.
        /// </summary>
        /// <param name="tc">Reference to owning TreeControl.</param>
        /// <param name="nc">Reference to NodeCollection instance.</param>
        /// <param name="g">Reference to Graphics instance to draw into.</param>
        /// <param name="clipRectangle">Clipping rectangle used when drawing.</param>
        /// <param name="preDraw">True when drawing before children and fales for drawing after.</param>
        public virtual void Draw(TreeControl tc,
                                 NodeCollection nc,
                                 Graphics g,
                                 Rectangle clipRectangle,
                                 bool preDraw)
        {
            if (preDraw)
            {
                // Only draw lines and boxes if there is at least one child node
                if (nc.VisibleCount > 0)
                {
                    // Find out if lines and boxes needed drawing
                    bool showLines      = ShowLines(tc, nc);
                    bool showBoxes      = ShowBoxes(tc, nc);
                    bool showIndicators = (IsRootCollection(tc, nc) && (tc.Indicators != Indicators.None)) ||
                                          (!IsRootCollection(tc, nc) && (tc.Indicators == Indicators.AtGroup));

                    // Is there any drawing to perform?
                    if (showLines || showBoxes || showIndicators)
                    {
                        Pen lineDashPen = tc.GetCacheLineDashPen();

                        // Cache the whole rectangle used for drawing
                        Rectangle ncBounds = nc.Cache.Bounds;

                        // Find the size of space taken up with indicators
                        Size indicatorSize = showIndicators ? tc.IndicatorSize : Size.Empty;

                        // Perform any adjustment for drawing within the bounds
                        AdjustBeforeDrawing(tc, nc, ref ncBounds);

                        // Cache the mid and right hand side of the lines column
                        int xMid   = ncBounds.Left + indicatorSize.Width + (tc.ColumnWidth / 2) - 1;
                        int xRight = ncBounds.Left + indicatorSize.Width + tc.ColumnWidth;

                        // Need to adjust drawing child connecting lines, so that wider than one
                        // pixel pens start from left of vertical for top and bottom children, but
                        // are placed to the right of middle children.
                        int xMidAdjustL = xMid - (tc.LineWidth / 2);
                        int xMidAdjustR = xMid + 1;

                        // Find the first and last visible nodes
                        int firstVisible = nc.FirstVisibleIndex;
                        int lastVisible  = nc.LastVisibleIndex;

                        // Find the first and last nodes mid points
                        int yMidFirst = nc[firstVisible].Cache.Bounds.Top + (nc[firstVisible].Cache.Bounds.Height / 2);
                        int yMidLast  = nc[lastVisible].Cache.Bounds.Top + (nc[lastVisible].Cache.Bounds.Height / 2);

                        // No point drawing line after end of clipping rectangle
                        if (yMidLast > clipRectangle.Bottom)
                        {
                            yMidLast = clipRectangle.Bottom;
                        }

                        // Do we need to draw the long vertical line?
                        if (showLines)
                        {
                            // Draw the long vertical line down the middle
                            if (IsRootCollection(tc, nc))
                            {
                                // No point drawing line before start of clipping rectangle
                                if (yMidFirst < clipRectangle.Top)
                                {
                                    yMidFirst = clipRectangle.Top;

                                    // Adjust starting point up so dot/dash lines are consistent
                                    switch (tc.LineDashStyle)
                                    {
                                    case LineDashStyle.Dot:
                                        yMidFirst -= yMidFirst % (2 * tc.LineWidth);
                                        break;

                                    case LineDashStyle.Dash:
                                        yMidFirst -= yMidFirst % (4 * tc.LineWidth);
                                        break;
                                    }
                                }

                                // We are root collection, so draw from the first node to the last
                                g.DrawLine(lineDashPen, xMid, yMidFirst, xMid, yMidLast);
                            }
                            else
                            {
                                // Not at root, so draw from top of column to the last node
                                g.DrawLine(lineDashPen, xMid, ncBounds.Top, xMid, yMidLast);
                            }
                        }

                        // Process each child node in turn, drawing horizontal line and any box
                        for (int i = nc.ChildFromY(clipRectangle.Top); i < nc.Count; i++)
                        {
                            if (DrawNode(tc, nc[i], g, clipRectangle, showLines, showBoxes,
                                         showIndicators, (i == 0) || (i == (nc.Count - 1)),
                                         lineDashPen, xMidAdjustL, xMidAdjustR, xMid, xRight,
                                         ncBounds.Left))
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
 /// <summary>
 /// Adjust the total bounds of the collection into the bounds available for drawing.
 /// </summary>
 /// <param name="tc">Reference to owning TreeControl.</param>
 /// <param name="nc">Reference to NodeCollection instance.</param>
 /// <param name="ncBounds">Drawing bounds to draw within.</param>
 public virtual void AdjustBeforeDrawing(TreeControl tc, NodeCollection nc, ref Rectangle ncBounds)
 {
     // By default we having no changes to make
 }
Exemplo n.º 5
0
 /// <summary>
 /// Find if the provided rectangle intersects the bounds of the node collection.
 /// </summary>
 /// <param name="tc">Reference to owning TreeControl.</param>
 /// <param name="nc">Reference to NodeCollection instance.</param>
 /// <param name="rectangle">Rectangle to compare against.</param>
 /// <returns>True if intersecting; otherwise false.</returns>
 public virtual bool IntersectsWith(TreeControl tc, NodeCollection nc, Rectangle rectangle)
 {
     return(nc.Cache.Bounds.IntersectsWith(rectangle));
 }
Exemplo n.º 6
0
 /// <summary>
 /// Defines the bounding rectangle of the collection.
 /// </summary>
 /// <param name="tc">Reference to owning TreeControl.</param>
 /// <param name="nc">Reference to NodeCollection instance.</param>
 /// <param name="bounds">Bounding rectangle of collection.</param>
 public virtual void SetBounds(TreeControl tc, NodeCollection nc, Rectangle bounds)
 {
     // Update cache bounds using new value
     nc.Cache.Bounds = bounds;
 }
Exemplo n.º 7
0
        private void SynchronizeCollections(NodeCollection orig,
                                            NodeCollection copy,
                                            ITypeDescriptorContext context)
        {
            // Make a note of all original nodes that are still in copy
            Hashtable both = new Hashtable();

            // First pass, scan looking for nodes that are in original and copy
            foreach (Node copyChild in copy)
            {
                // Does this node have an back pointer to its original?
                if (copyChild.Original != null)
                {
                    // Then make a note that it is in both collections
                    both.Add(copyChild.Original, copyChild.Original);

                    // Update the original from the copy
                    copyChild.Original.UpdateInstance(copyChild);
                }
            }

            int origCount = orig.Count;

            // Second pass, remove nodes in the original but not in the copy
            for (int i = 0; i < origCount; i++)
            {
                // Get access to the indexed node from original
                Node origChild = orig[i];

                // If not in the found collection...
                if (!both.ContainsKey(origChild))
                {
                    // ...then it has been removed from the copy, so delete it
                    orig.Remove(origChild);

                    // Must remove from context container so it is removed from designer tray
                    context.Container.Remove(origChild as IComponent);

                    // Reduce the count and index to reflect change in collection contents
                    --i;
                    --origCount;
                }
            }

            int copyCount = copy.Count;

            // Third pass, add new nodes from copy but not in original
            for (int i = 0; i < copyCount; i++)
            {
                // Get access to the indexed node from copy
                Node copyChild = copy[i];

                // If this node is a new one then it will not have an 'original' property
                if (copyChild.Original == null)
                {
                    // Add this node into the original at indexed position
                    orig.Insert(i, copyChild);

                    // Must add into context container so it is added to the designer tray
                    context.Container.Add(copyChild as IComponent);
                }
            }

            // Fourth pass, process all children
            foreach (Node copyChild in copy)
            {
                // Does this node has an back pointer to its original?
                if (copyChild.Original != null)
                {
                    // Recurse down into the child collections
                    SynchronizeCollections(copyChild.Original.Nodes, copyChild.Nodes, context);
                }
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Helper function that indicates if given collection is the root.
 /// </summary>
 /// <param name="tc">Reference to owning TreeControl.</param>
 /// <param name="nc">Reference to NodeCollection instance.</param>
 /// <returns></returns>
 public override bool IsRootCollection(TreeControl tc, NodeCollection nc)
 {
     return((nc.ParentNode != null) &&
            (nc.ParentNode.ParentNodes == tc.Nodes));
 }
Exemplo n.º 9
0
        /// <summary>
        /// Draw the NodeCollection instance.
        /// </summary>
        /// <param name="tc">Reference to owning TreeControl.</param>
        /// <param name="nc">Reference to NodeCollection instance.</param>
        /// <param name="g">Reference to Graphics instance to draw into.</param>
        /// <param name="clipRectangle">Clipping rectangle used when drawing.</param>
        /// <param name="preDraw">True when drawing before children and fales for drawing after.</param>
        public override void Draw(TreeControl tc,
                                  NodeCollection nc,
                                  Graphics g,
                                  Rectangle clipRectangle,
                                  bool preDraw)
        {
            // The real root never has anything to draw
            if (!IsRealRootCollection(tc, nc))
            {
                // Let base class do its stuff
                base.Draw(tc, nc, g, clipRectangle, preDraw);

                // Only draw the extra separating lines and image column after children are drawn
                if (!preDraw)
                {
                    // The root within each group might have something to do
                    if (IsRootCollection(tc, nc))
                    {
                        // Do we need to account for the image box column?
                        if (tc.GroupImageBox && tc.GroupImageBoxColumn)
                        {
                            // Recover the actual control drawing area in node space
                            Rectangle drawRect = tc.ClientToNodeSpace(tc.DrawRectangle);

                            // Get the bounding rectangle of the collection
                            Rectangle ncBounds = nc.Cache.Bounds;

                            // If this the first visible collection
                            bool firstVisibleCollection = (ncBounds.Top <= drawRect.Top) && (ncBounds.Bottom >= drawRect.Top);

                            // Adjust backwards to account for group indent
                            ncBounds.X -= tc.GroupIndentLeft;

                            // Adjust to just the image column width
                            ncBounds.Width = tc.GroupImageBoxWidth;

                            // Draw the image column color
                            g.FillRectangle(tc.GetCacheGroupImageBoxColumnBrush(), ncBounds);

                            // Draw the separator line on right hand side of column
                            g.DrawLine(tc.GetCacheGroupImageBoxLinePen(), ncBounds.Right, ncBounds.Top,
                                       ncBounds.Right, ncBounds.Bottom - 1);

                            // We draw top and bottom collection separators, if we have no border
                            if (tc.BorderStyle == TreeBorderStyle.None)
                            {
                                // Draw the separator line on right side of control
                                g.DrawLine(tc.GetCacheGroupImageBoxLinePen(), drawRect.Right - 1, ncBounds.Top,
                                           drawRect.Right - 1, ncBounds.Bottom - 1);

                                // The first collection drawn on the control...
                                if (firstVisibleCollection)
                                {
                                    // ...needs a top line separator
                                    g.DrawLine(tc.GetCacheGroupImageBoxLinePen(), ncBounds.Right, drawRect.Top,
                                               drawRect.Right - 1, drawRect.Top);
                                }

                                bool lastSibling = true;

                                // Then search siblings...
                                for (int i = nc.ParentNode.Index + 1; i < nc.ParentNode.ParentNodes.Count; i++)
                                {
                                    Node next = nc.ParentNode.ParentNodes[i];

                                    // For a node that is visible...
                                    if (next.Visible)
                                    {
                                        lastSibling = false;
                                        break;
                                    }
                                }

                                // If the last sibling, or collection runs off end of control
                                if (lastSibling || (ncBounds.Bottom > drawRect.Bottom))
                                {
                                    // Find the bottom line for drawing
                                    int bottom = ncBounds.Bottom - 1;

                                    // If we party run off end of the control the use end of control instead
                                    if (bottom >= drawRect.Bottom)
                                    {
                                        bottom = drawRect.Bottom - 1;
                                    }

                                    // ...then draw separator line at bottom of collection
                                    g.DrawLine(tc.GetCacheGroupImageBoxLinePen(), ncBounds.Right, bottom,
                                               drawRect.Right - 1, bottom);
                                }
                            }
                        }
                    }
                }
            }
        }