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); }
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; } }
internal void SetParent(SmartTreeNode parentNode) { _parentNode = parentNode; foreach (SmartTreeNode node in _nodes) { node.SetParent(this); } }
private SmartTreeNode FindRecentSelectedNode() { SmartTreeNode recentSelectedNode = null; if (_selectedNodes.Count > 0) { recentSelectedNode = _selectedNodes[_selectedNodes.Count - 1]; } return(recentSelectedNode); }
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; } } }
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); }
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)); } } }
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); }
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); } }
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; } } } }
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)); } } }
private void RemovedFromSelectedNodesCollection(SmartTreeNode node) { _selectedNodes.Remove(node); node.IsSelected = false; RepaintNode(node); }
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); }
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; } } }
public SmartTreeNode(string label, SmartTreeNode[] children) : this(label) { _nodes.AddRange(children); }
internal void SetParent(SmartTreeNode parentNode) { _parentNode = parentNode; foreach( SmartTreeNode node in _nodes ) { node.SetParent(this); } }
internal void SetNextNode(SmartTreeNode nextNode) { _nextNode = nextNode; }
public SmartTreeEventHandlerArgs(SmartTreeNode node) { _node = node; }
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); }
internal void RepaintNode(SmartTreeNode node) { _contentPanel.Invalidate(node.GetHighlightArea()); }
internal void SetPreviousNode(SmartTreeNode previousNode) { _previousNode = previousNode; }
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; }
public SmartTreeNode(string label, int imageIndex, int selectedImageIndex, SmartTreeNode[] children) : this(label, imageIndex, selectedImageIndex) { _nodes.AddRange(children); }
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); }