예제 #1
0
 internal HitTestResult HitTest(SmartTreeNode node, Point location)
 {
     if (node.Bounds.Contains(location))
     {
         if (node.GetHighlightArea().Contains(location))
         {
             return(HitTestResult.NodeContent);
         }
         if (node.Nodes.Count > 0)
         {
             int       iconHeight        = Properties.Resources.Plus.Height;
             int       imageLocationY    = node.Bounds.Top + ((int)(_ownerTree.Font.SizeInPoints * 2) - iconHeight) / 2;
             Rectangle expanderRectangle = new Rectangle(node.Bounds.Left, imageLocationY,
                                                         Properties.Resources.Plus.Width,
                                                         Properties.Resources.Plus.Height);
             if (expanderRectangle.Contains(location))
             {
                 return(HitTestResult.Expander);
             }
         }
         if (node.HasCheckBox)
         {
             int       iconWidth         = Properties.Resources.Plus.Width;
             int       checkBoxLocationY = node.Bounds.Top + ((int)(_ownerTree.Font.SizeInPoints * 2) - SmartTree.CheckBoxHeight) / 2;
             int       checkBoxLocationX = node.Bounds.Left + iconWidth + _ownerTree.HorizontalSpace;
             Rectangle checkBoxRectangle = new Rectangle(checkBoxLocationX, checkBoxLocationY,
                                                         SmartTree.CheckBoxWidth, SmartTree.CheckBoxHeight);
             if (checkBoxRectangle.Contains(location))
             {
                 return(HitTestResult.CheckBox);
             }
         }
     }
     return(HitTestResult.None);
 }
예제 #2
0
        private void OnContentPanelPaint(object sender, PaintEventArgs e)
        {
            // Draw the nodes
            int x = HorizontalSpace;
            int y = VerticalSpace;
            int horizontalOffset = _expanderWidth + HorizontalSpace;

            if (_rootNodes.Count > 0)
            {
                Rectangle     treeBounds    = new Rectangle(0, 0, HorizontalSpace, VerticalSpace);
                SmartTreeNode current       = _rootNodes[0];
                Rectangle     smartTreeRect = RectangleToScreen(ClientRectangle);
                smartTreeRect = _contentPanel.RectangleToClient(smartTreeRect);

                while (current != null)
                {
                    current.SetTreeView(this);
                    Rectangle contentArea = CalculateContentArea(x, y, current.GetContentSize());
                    if (contentArea.IntersectsWith(smartTreeRect))
                    {
                        PaintNode(current, e.Graphics, x, y);
                    }
                    treeBounds = Rectangle.Union(treeBounds, contentArea);
                    y         += contentArea.Height + VerticalSpace;
                    if (current.IsExpanded &&
                        current.Nodes.Count > 0)
                    {
                        current = current.Nodes[0];
                        x      += horizontalOffset;
                    }
                    else if (current.NextNode != null)
                    {
                        current = current.NextNode;
                    }
                    else
                    {
                        current = current.Parent;
                        x      -= horizontalOffset;
                        while (current != null)
                        {
                            if (current.NextNode != null)
                            {
                                current = current.NextNode;
                                break;
                            }
                            else
                            {
                                current = current.Parent;
                                x      -= horizontalOffset;
                            }
                        }
                    }
                }
                _contentPanel.Size = new Size(treeBounds.Width + 2 * HorizontalSpace, treeBounds.Height + VerticalSpace);
            }
            else
            {
                _contentPanel.Size = Size;
            }
        }
예제 #3
0
 internal void SetParent(SmartTreeNode parentNode)
 {
     _parentNode = parentNode;
     foreach (SmartTreeNode node in _nodes)
     {
         node.SetParent(this);
     }
 }
예제 #4
0
        private SmartTreeNode FindRecentSelectedNode()
        {
            SmartTreeNode recentSelectedNode = null;

            if (_selectedNodes.Count > 0)
            {
                recentSelectedNode = _selectedNodes[_selectedNodes.Count - 1];
            }
            return(recentSelectedNode);
        }
예제 #5
0
        private void OnContentPanelMouseDown(object sender, MouseEventArgs e)
        {
            SmartTreeNode node = GetNodeAt(e.X, e.Y);

            if (node != null)
            {
                FocusNode = node;
                switch (node.HitTest(node, e.Location))
                {
                case HitTestResult.NodeContent:
                    if ((ModifierKeys & Keys.Control) != 0)
                    {
                        if (node.IsSelected)
                        {
                            RemovedFromSelectedNodesCollection(node);
                        }
                        else
                        {
                            AddToSelectedNodesCollection(node);
                        }
                    }
                    else if ((ModifierKeys & Keys.Shift) != 0)    // Extend selection
                    {
                        SelectNodesBetween(FindRecentSelectedNode(), node);
                    }
                    else
                    {
                        ClearSelectedNodesCollection();
                        AddToSelectedNodesCollection(node);
                    }
                    break;

                case HitTestResult.Expander:
                    if (node.IsExpanded)
                    {
                        node.Collapse();
                    }
                    else
                    {
                        node.Expand();
                    }
                    _contentPanel.Invalidate(new Rectangle(0, node.Bounds.Top, _contentPanel.Right, _contentPanel.Bottom));
                    break;

                case HitTestResult.CheckBox:
                    node.Checked = !node.Checked;
                    _contentPanel.Invalidate(new Rectangle(
                                                 node.Bounds.Left + Properties.Resources.Plus.Width + HorizontalSpace,
                                                 node.Bounds.Top,
                                                 CheckBoxWidth,
                                                 node.Bounds.Height));
                    break;
                }
            }
        }
예제 #6
0
        private void SelectNodesBetween(SmartTreeNode node1, SmartTreeNode node2)
        {
            bool forward = node2.Bounds.Top > node1.Bounds.Top;

            if (forward)
            {
                SmartTreeNode current = node1;
                while (current != null &&
                       current != node2)
                {
                    AddToSelectedNodesCollection(current);
                    if (current.Nodes.Count > 0)
                    {
                        current = current.Nodes[0];
                    }
                    else if (current.NextNode != null)
                    {
                        current = current.NextNode;
                    }
                    else
                    {
                        if (current.Parent != null)
                        {
                            current = current.Parent.NextNode;
                        }
                        else
                        {
                            current = null; // done
                        }
                    }
                }
            }
            else
            {
                SmartTreeNode current = node1;
                while (current != null &&
                       current != node2)
                {
                    AddToSelectedNodesCollection(current);
                    if (current.PreviousNode != null)
                    {
                        current = current.PreviousNode;
                        while (current.Nodes.Count > 0)
                        {
                            current = current.Nodes[current.Nodes.Count - 1];
                        }
                    }
                    else if (current.Parent != null)
                    {
                        current = current.Parent;
                    }
                }
            }
            AddToSelectedNodesCollection(node2);
        }
예제 #7
0
 private void AddToSelectedNodesCollection(SmartTreeNode node)
 {
     if (!_selectedNodes.Contains(node))
     {
         _selectedNodes.Add(node);
         node.IsSelected = true;
         RepaintNode(node);
         if (AfterSelect != null)
         {
             AfterSelect(this, new SmartTreeEventHandlerArgs(node));
         }
     }
 }
예제 #8
0
      public TestForm() {
         InitializeComponent();
         _smartTree.ImageList = _imageList;

         _smartTree.Nodes.Clear();
         SmartTreeNode node0 = new SmartTreeNode("Root0:\nRoot0 Root0 ");
         SmartTreeNode node00 = new SmartTreeNode("Node00:\nNode00 Node00 Node00 Node00");
         node0.ImageIndex = 0;
         node0.HasCheckBox = true;
         node0.Nodes.Add(node00);
         SmartTreeNode node00a = new SmartTreeNode("Node00a:\nNode00a Node00a Node00a Node00a Node00a Node00a Node00a");
         node00a.HasCheckBox = true;
         node00a.Checked = true;
         node00.Nodes.Add(node00a);
         node0.Nodes.Add(new SmartTreeNode("Node01:\nNode01 Node01 Node01 Node01 Node01"));
         _smartTree.Nodes.Add(node0);
         SmartTreeNode node1 = new SmartTreeNode("Root1:\nRoot1 Root1 Root1");
         _smartTree.Nodes.Add(node1);
      }
예제 #9
0
 public SmartTreeNode GetNodeAt(int locationX, int locationY)
 {
     if (_rootNodes.Count > 0)
     {
         SmartTreeNode current = _rootNodes[0];
         while (current != null &&
                !current.Bounds.Contains(locationX, locationY))
         {
             if (current.IsExpanded &&
                 current.Nodes.Count > 0)
             {
                 current = current.Nodes[0];
             }
             else if (current.NextNode != null)
             {
                 current = current.NextNode;
             }
             else
             {
                 current = current.Parent;
                 while (current != null)
                 {
                     if (current.NextNode != null)
                     {
                         current = current.NextNode;
                         break;
                     }
                     else
                     {
                         current = current.Parent;
                     }
                 }
             }
         }
         return(current);
     }
     else
     {
         return(null);
     }
 }
예제 #10
0
        private void ProcessKeyDown()
        {
            SmartTreeNode currentFocus = FocusNode;

            if (currentFocus == null)
            {
                if (_rootNodes.Count > 0)
                {
                    FocusNode = _rootNodes[0];
                }
            }
            else
            {
                if (currentFocus.Nodes.Count > 0)
                {
                    FocusNode = currentFocus.Nodes[0];
                }
                else if (currentFocus.NextNode != null)
                {
                    FocusNode = currentFocus.NextNode;
                }
                else
                {
                    while (currentFocus != null)
                    {
                        currentFocus = currentFocus.Parent;
                        if (currentFocus.NextNode != null)
                        {
                            currentFocus = currentFocus.NextNode;
                            break;
                        }
                    }
                    if (currentFocus != null)
                    {
                        FocusNode = currentFocus;
                    }
                }
            }
        }
예제 #11
0
 private void AddToSelectedNodesCollection(SmartTreeNode node) {
    if( !_selectedNodes.Contains(node) ) {
       _selectedNodes.Add(node);
       node.IsSelected = true;
       RepaintNode(node);
       if(AfterSelect != null) {
          AfterSelect(this, new SmartTreeEventHandlerArgs(node));
       }
    }
 }
예제 #12
0
 private void RemovedFromSelectedNodesCollection(SmartTreeNode node) {
    _selectedNodes.Remove(node);
    node.IsSelected = false;
    RepaintNode(node);
 }
예제 #13
0
 private void SelectNodesBetween(SmartTreeNode node1, SmartTreeNode node2) {
    bool forward = node2.Bounds.Top > node1.Bounds.Top;
    if( forward ) {
       SmartTreeNode current = node1;
       while(current != null
          && current != node2) {
          AddToSelectedNodesCollection(current);
          if( current.Nodes.Count > 0 ) {
             current = current.Nodes[0];
          }
          else if( current.NextNode != null ) {
             current = current.NextNode;
          }
          else {
             if( current.Parent != null ) {
                current = current.Parent.NextNode;
             }
             else {
                current = null;  // done
             }
          }
       }
    }
    else {
       SmartTreeNode current = node1;
       while( current != null
          && current != node2 ) {
          AddToSelectedNodesCollection(current);
          if(current.PreviousNode != null ) {
             current = current.PreviousNode;
             while( current.Nodes.Count > 0 ) {
                current = current.Nodes[current.Nodes.Count - 1];
             }
          }
          else if(current.Parent != null ) {
             current = current.Parent;
          }
       }
    }
    AddToSelectedNodesCollection(node2);
 }
예제 #14
0
 private void OnContentPanelMouseDown(object sender, MouseEventArgs e) {
    SmartTreeNode node = GetNodeAt(e.X, e.Y);
    if( node != null ) {
       FocusNode = node;
       switch(node.HitTest(node, e.Location)) {
          case HitTestResult.NodeContent:
             if( ( ModifierKeys & Keys.Control ) != 0 ) {
                if( node.IsSelected ) {
                   RemovedFromSelectedNodesCollection(node);
                }
                else {
                   AddToSelectedNodesCollection(node);
                }
             }
             else if( ( ModifierKeys & Keys.Shift ) != 0 ) { // Extend selection
                SelectNodesBetween(FindRecentSelectedNode(), node);
             }
             else {
                ClearSelectedNodesCollection();
                AddToSelectedNodesCollection(node);
             }
             break;
          case HitTestResult.Expander:
             if( node.IsExpanded ) {
                node.Collapse();
             }
             else {
                node.Expand();
             }
             _contentPanel.Invalidate(new Rectangle(0, node.Bounds.Top, _contentPanel.Right, _contentPanel.Bottom));
             break;
          case HitTestResult.CheckBox:
             node.Checked = !node.Checked;
             _contentPanel.Invalidate(new Rectangle(
                node.Bounds.Left + Properties.Resources.Plus.Width + HorizontalSpace,
                node.Bounds.Top,
                CheckBoxWidth,
                node.Bounds.Height));
             break;
       }
    }
 }
예제 #15
0
 public SmartTreeNode(string label, SmartTreeNode[] children) 
 : this(label) {
    _nodes.AddRange(children);
 }
예제 #16
0
 internal void SetParent(SmartTreeNode parentNode) {
    _parentNode = parentNode;
    foreach( SmartTreeNode node in _nodes ) {
       node.SetParent(this);
    }
 }
예제 #17
0
 private void RemovedFromSelectedNodesCollection(SmartTreeNode node)
 {
     _selectedNodes.Remove(node);
     node.IsSelected = false;
     RepaintNode(node);
 }
예제 #18
0
 internal void SetNextNode(SmartTreeNode nextNode)
 {
     _nextNode = nextNode;
 }
 public SmartTreeEventHandlerArgs(SmartTreeNode node) {
    _node = node;
 }
예제 #20
0
 public SmartTreeEventHandlerArgs(SmartTreeNode node)
 {
     _node = node;
 }
예제 #21
0
        private void PaintNode(SmartTreeNode theNode, Graphics g, int locationX, int locationY)
        {
            // Icon dimensions
            int imageMidpointX = locationX + _expanderWidth / 2;
            int imageMidpointY = locationY + (int)(Font.SizeInPoints * 2) / 2;

            // Node dimensions
            Rectangle contentArea = CalculateContentArea(locationX, locationY, theNode.GetContentSize());
            int       nodeHeight  = contentArea.Height;
            int       nodeBottom  = locationY + nodeHeight;

            // Update node bounds
            theNode.Bounds = new Rectangle(locationX, locationY,
                                           _expanderWidth + HorizontalSpace + contentArea.Width,
                                           contentArea.Height);

            // Draw lines
            using (Pen pen = new Pen(LineColor)) {
                pen.DashStyle = DashStyle;

                // Horizontal Line
                g.DrawLine(pen, imageMidpointX,
                           imageMidpointY,
                           contentArea.Left, imageMidpointY);

                Point verticalLineTop    = new Point(imageMidpointX, imageMidpointY);
                Point verticalLineBottom = verticalLineTop;

                // Vertical line upwards
                if (theNode.Parent != null || theNode.PreviousNode != null)
                {
                    verticalLineTop = new Point(imageMidpointX, locationY - VerticalSpace);
                }

                // Vertical line downwards
                if (theNode.NextNode != null)
                {
                    verticalLineBottom = new Point(imageMidpointX, nodeBottom);
                }

                if (verticalLineTop != verticalLineBottom)
                {
                    g.DrawLine(pen, verticalLineTop, verticalLineBottom);
                }
            }

            // Draw plus and minus
            if (theNode.Nodes.Count > 0)
            {
                int imageLocationY = locationY + ((int)(Font.SizeInPoints * 2) - _expanderHeight) / 2;
                if (theNode.IsExpanded)
                {
                    g.DrawImage(_expanderExpandedImage, locationX, imageLocationY);
                }
                else
                {
                    g.DrawImage(_expanderCollapsedImage, locationX, imageLocationY);
                }
            }

            // draw the vertical dot line for the parent nodes if necessary
            using (Pen pen = new Pen(LineColor)) {
                pen.DashStyle = DashStyle;
                SmartTreeNode parentNode = theNode.Parent;
                while (parentNode != null)
                {
                    if (parentNode.NextNode != null)
                    {
                        int parentImageLocationX = parentNode.Bounds.X + _expanderWidth / 2;
                        g.DrawLine(pen, parentImageLocationX,
                                   locationY - VerticalSpace,
                                   parentImageLocationX,
                                   locationY + nodeHeight);
                    }
                    parentNode = parentNode.Parent;
                }
            }

            // Draw checkbox:
            if (theNode.HasCheckBox)
            {
                int checkBoxLocationY = locationY + ((int)(Font.SizeInPoints * 2) - CheckBoxHeight) / 2;
                if (theNode.Checked)
                {
                    CheckBoxRenderer.DrawCheckBox(g, new Point(contentArea.Left, checkBoxLocationY), CheckBoxState.CheckedNormal);
                }
                else
                {
                    CheckBoxRenderer.DrawCheckBox(g, new Point(contentArea.Left, checkBoxLocationY), CheckBoxState.UncheckedNormal);
                }
                // Update text area to account for the space needed by the checkbox:
                contentArea = new Rectangle(contentArea.Left + CheckBoxWidth, contentArea.Top, contentArea.Width, contentArea.Height);
            }

            theNode.DrawContent(g, contentArea);
        }
예제 #22
0
 internal void RepaintNode(SmartTreeNode node)
 {
     _contentPanel.Invalidate(node.GetHighlightArea());
 }
예제 #23
0
 internal void SetNextNode(SmartTreeNode nextNode) {
    _nextNode = nextNode;
 }
예제 #24
0
 internal void SetPreviousNode(SmartTreeNode previousNode) {
    _previousNode = previousNode;
 }
예제 #25
0
 internal void SetPreviousNode(SmartTreeNode previousNode)
 {
     _previousNode = previousNode;
 }
예제 #26
0
 internal HitTestResult HitTest(SmartTreeNode node, Point location) {
    if( node.Bounds.Contains(location) ) {
       if( node.GetHighlightArea().Contains(location) ) {
          return HitTestResult.NodeContent;
       }
       if( node.Nodes.Count > 0 ) {
          int iconHeight = Properties.Resources.Plus.Height;
          int imageLocationY = node.Bounds.Top + ( (int) ( _ownerTree.Font.SizeInPoints * 2 ) - iconHeight ) / 2;
          Rectangle expanderRectangle = new Rectangle(node.Bounds.Left, imageLocationY,
                                                      Properties.Resources.Plus.Width,
                                                      Properties.Resources.Plus.Height);
          if( expanderRectangle.Contains(location) ) {
             return HitTestResult.Expander;
          }
       }
       if( node.HasCheckBox ) {
          int iconWidth = Properties.Resources.Plus.Width;
          int checkBoxLocationY = node.Bounds.Top + ( (int) ( _ownerTree.Font.SizeInPoints * 2 ) - SmartTree.CheckBoxHeight ) / 2;
          int checkBoxLocationX = node.Bounds.Left + iconWidth + _ownerTree.HorizontalSpace;
          Rectangle checkBoxRectangle = new Rectangle(checkBoxLocationX, checkBoxLocationY,
             SmartTree.CheckBoxWidth, SmartTree.CheckBoxHeight);
          if( checkBoxRectangle.Contains(location) ) {
             return HitTestResult.CheckBox;
          }
       }
    }
    return HitTestResult.None;
 }
예제 #27
0
 internal void RepaintNode(SmartTreeNode node) {
    _contentPanel.Invalidate(node.GetHighlightArea());
 }
예제 #28
0
 public SmartTreeNode(string label, int imageIndex, 
    int selectedImageIndex, SmartTreeNode[] children) 
    : this(label, imageIndex, selectedImageIndex) {
    _nodes.AddRange(children);
 }
예제 #29
0
      private void PaintNode(SmartTreeNode theNode, Graphics g, int locationX, int locationY) {
         // Icon dimensions
         int imageMidpointX = locationX + _expanderWidth / 2;
         int imageMidpointY = locationY + (int) ( Font.SizeInPoints * 2 ) / 2;

         // Node dimensions
         Rectangle contentArea = CalculateContentArea(locationX, locationY, theNode.GetContentSize());
         int nodeHeight = contentArea.Height;
         int nodeBottom = locationY + nodeHeight;

         // Update node bounds
         theNode.Bounds = new Rectangle(locationX, locationY,
            _expanderWidth + HorizontalSpace + contentArea.Width,
            contentArea.Height);

         // Draw lines
         using( Pen pen = new Pen(LineColor) ) {
            pen.DashStyle = DashStyle;

            // Horizontal Line
            g.DrawLine(pen, imageMidpointX,
                       imageMidpointY,
                       contentArea.Left, imageMidpointY);

            Point verticalLineTop = new Point(imageMidpointX, imageMidpointY);
            Point verticalLineBottom = verticalLineTop;

            // Vertical line upwards
            if( theNode.Parent != null || theNode.PreviousNode != null ) {
               verticalLineTop = new Point(imageMidpointX, locationY - VerticalSpace);
            }

            // Vertical line downwards
            if( theNode.NextNode != null ) {
               verticalLineBottom = new Point(imageMidpointX, nodeBottom);
            }

            if( verticalLineTop != verticalLineBottom ) {
               g.DrawLine(pen, verticalLineTop, verticalLineBottom);
            }
         }

         // Draw plus and minus
         if( theNode.Nodes.Count > 0 ) {
            int imageLocationY = locationY + ( (int) ( Font.SizeInPoints * 2 ) - _expanderHeight ) / 2;
            if( theNode.IsExpanded ) {
               g.DrawImage(_expanderExpandedImage, locationX, imageLocationY);
            }
            else {
               g.DrawImage(_expanderCollapsedImage, locationX, imageLocationY);
            }
         }

         // draw the vertical dot line for the parent nodes if necessary
         using( Pen pen = new Pen(LineColor) ) {
            pen.DashStyle = DashStyle;
            SmartTreeNode parentNode = theNode.Parent;
            while( parentNode != null ) {
               if( parentNode.NextNode != null ) {
                  int parentImageLocationX = parentNode.Bounds.X + _expanderWidth/2;
                  g.DrawLine(pen, parentImageLocationX,
                             locationY - VerticalSpace,
                             parentImageLocationX,
                             locationY + nodeHeight);
               }
               parentNode = parentNode.Parent;
            }
         }

         // Draw checkbox:
         if(theNode.HasCheckBox) {
            int checkBoxLocationY = locationY + ( (int) ( Font.SizeInPoints * 2 ) - CheckBoxHeight ) / 2;
            if( theNode.Checked ) {
               CheckBoxRenderer.DrawCheckBox(g, new Point(contentArea.Left, checkBoxLocationY), CheckBoxState.CheckedNormal);
            }
            else {
               CheckBoxRenderer.DrawCheckBox(g, new Point(contentArea.Left, checkBoxLocationY), CheckBoxState.UncheckedNormal);
            }
            // Update text area to account for the space needed by the checkbox:
            contentArea = new Rectangle(contentArea.Left + CheckBoxWidth, contentArea.Top, contentArea.Width, contentArea.Height);
         }

         theNode.DrawContent(g, contentArea);
      }