using System; using System.Drawing; using DevComponents.Tree.Layout; namespace DevComponents.Tree.Display { /// /// Summary description for NodeDisplay. /// public class NodeDisplay { #region Private Variables private Point m_Offset=Point.Empty; private Point m_LockedOffset=Point.Empty; private TreeGX m_Tree=null; #if !TRIAL internal static bool keyInvalid=false; #endif #endregion /// Creates new instance of the class /// Object to initialize class with. public NodeDisplay(TreeGX tree) { m_Tree=tree; } /// /// Paints the layout on canvas. /// public virtual void Paint(Graphics g, Rectangle clipRectangle) { } /// /// Gets or sets the offset of the tree content relative to the size of the container control. /// public virtual Point Offset { get { if(!m_LockedOffset.IsEmpty) return m_LockedOffset; Node displayNode=m_Tree.GetDisplayRootNode(); if(displayNode==null) return Point.Empty;; Size nodesSize = m_Tree.GetScreenSize(new Size(m_Tree.NodeLayout.Width, m_Tree.NodeLayout.Height)); // Must change offset value since map layout assumes that root node is in the center // of container control. if(m_Tree.NodeLayout is NodeMapLayout && m_Tree.AutoScroll) { Point p=m_Offset; Point displayNodeChildLocation = new Point(Math.Abs((int)(displayNode.ChildNodesBounds.Left * m_Tree.Zoom)), Math.Abs((int)(displayNode.ChildNodesBounds.Top * m_Tree.Zoom))); p.Offset(displayNodeChildLocation.X, displayNodeChildLocation.Y); int offsetX=0, offsetY=0; if(m_Tree.CenterContent && m_Tree.Height>nodesSize.Height) { offsetY=(m_Tree.Height-nodesSize.Height)/2; } if(m_Tree.CenterContent && m_Tree.Width>nodesSize.Width) { offsetX=(m_Tree.Width-nodesSize.Width)/2; } p.Offset(offsetX,offsetY); return m_Tree.GetLayoutPosition(p); } else if(m_Tree.NodeLayout is Layout.NodeDiagramLayout && m_Tree.AutoScroll) { Point p=m_Offset; int offsetX=0, offsetY=0; if(m_Tree.CenterContent && m_Tree.Height>nodesSize.Height) offsetY=(m_Tree.Height-nodesSize.Height)/2; if(m_Tree.CenterContent && m_Tree.Width>nodesSize.Width) offsetX=(m_Tree.Width-nodesSize.Width)/2; p.Offset(offsetX,offsetY); return m_Tree.GetLayoutPosition(p); } else return m_Offset; } set {m_Offset=value;} } /// Gets or sets whether offset is locked, i.e. cannot be changed. public bool LockOffset { get {return (!m_LockedOffset.IsEmpty);} set { if(value) m_LockedOffset=this.Offset; else m_LockedOffset=Point.Empty; } } /// /// Sets locked offset to specific value. Point.Empty means there is no locked offset set. /// /// New locked offset. public void SetLockedOffset(Point p) { m_LockedOffset=p; } /// /// /// /// public Point GetLockedOffset() { return m_LockedOffset; } /// /// Returns the default offset for the tree content relative to the size of the container. /// public virtual Point DefaultOffset { get { Node displayNode=m_Tree.GetDisplayRootNode(); if(displayNode==null) return Point.Empty;; if(m_Tree.NodeLayout is NodeMapLayout && m_Tree.Nodes.Count>0) { if(!m_Tree.CenterContent) return new Point(Math.Abs(displayNode.ChildNodesBounds.Left),Math.Abs(displayNode.ChildNodesBounds.Top)); else return new Point(m_Tree.SelectionBoxSize+(m_Tree.Width - m_Tree.SelectionBoxSize * 2 - m_Tree.NodeLayout.Width) / 2 + Math.Abs(displayNode.ChildNodesBounds.Left), m_Tree.SelectionBoxSize + (m_Tree.Height - m_Tree.SelectionBoxSize * 2 - m_Tree.NodeLayout.Height) / 2 + Math.Abs(displayNode.ChildNodesBounds.Top)); } if(m_Tree.NodeLayout is Layout.NodeDiagramLayout) { if(!m_Tree.CenterContent) return m_Tree.ClientRectangle.Location; else return new Point((m_Tree.Width-m_Tree.NodeLayout.Width)/2,(m_Tree.Height-m_Tree.NodeLayout.Height)/2); } else return m_Tree.ClientRectangle.Location; } } /// /// Gets or sets the reference to the tree control managed by display class. /// protected virtual TreeGX Tree { get {return m_Tree;} set {m_Tree=value;} } internal static Rectangle GetNodeRectangle(eNodeRectanglePart part, Node node, Point offset) { Rectangle r=Rectangle.Empty; if(part==eNodeRectanglePart.CellsBounds) { r=node.CellsBoundsRelative; if(!r.IsEmpty) { r.Offset(offset); r.Offset(node.BoundsRelative.Location); } } else if(part==eNodeRectanglePart.ExpandBounds) { r=node.ExpandPartRectangleRelative; if(!r.IsEmpty) { r.Offset(offset); r.Offset(node.BoundsRelative.Location); } } else if(part==eNodeRectanglePart.CommandBounds) { r=node.CommandBoundsRelative; if(!r.IsEmpty) { r.Offset(offset); r.Offset(node.BoundsRelative.Location); } } else if(part==eNodeRectanglePart.NodeContentBounds) { r=node.ContentBounds; if(!r.IsEmpty) { r.Offset(offset); r.Offset(node.BoundsRelative.Location); } } else if(part==eNodeRectanglePart.NodeBounds) { r=node.BoundsRelative; if(!r.IsEmpty) r.Offset(offset); } else if(part==eNodeRectanglePart.ChildNodeBounds) { r=node.ChildNodesBounds; if(!r.IsEmpty) { //r.Offset(node.Bounds.Location); r.Offset(offset); } } return r; } internal static Rectangle GetCellRectangle(eCellRectanglePart part, Cell cell, Point offset) { Rectangle r=Rectangle.Empty; // If cell parent is not assigned rectangle cannot be returned. if(cell.Parent==null) return r; if(part==eCellRectanglePart.CheckBoxBounds) { r=cell.CheckBoxBoundsRelative; if(!r.IsEmpty) { r.Offset(offset); r.Offset(cell.Parent.BoundsRelative.Location); } } else if(part==eCellRectanglePart.ImageBounds) { r=cell.ImageBoundsRelative; if(!r.IsEmpty) { r.Offset(offset); r.Offset(cell.Parent.BoundsRelative.Location); } } else if(part==eCellRectanglePart.TextBounds) { r=cell.TextContentBounds; if(!r.IsEmpty) { r.Offset(offset); r.Offset(cell.Parent.BoundsRelative.Location); } } else if(part==eCellRectanglePart.CellBounds) { r=cell.BoundsRelative; if(!r.IsEmpty) { r.Offset(offset); } } return r; } internal static bool DrawExpandPart(Node node) { if(node.Nodes.Count>0 && node.ExpandVisibility!=eNodeExpandVisibility.Hidden || node.ExpandVisibility==eNodeExpandVisibility.Visible) return true; return false; } protected NodeExpandDisplay GetExpandDisplay(eExpandButtonType e) { NodeExpandDisplay d=null; switch(e) { case eExpandButtonType.Ellipse: d=new NodeExpandEllipseDisplay(); break; case eExpandButtonType.Rectangle: d=new NodeExpandRectDisplay(); break; case eExpandButtonType.Image: d=new NodeExpandImageDisplay(); break; } return d; } protected bool IsRootNode(Node node) { return NodeOperations.IsRootNode(m_Tree,node); } protected ElementStyle GetDefaultNodeStyle() { ElementStyle style=new ElementStyle(); style.TextColorSchemePart=eColorSchemePart.ItemText; return style; } public void MoveHostedControls() { Point offset=this.Offset; float zoom = this.Tree.Zoom; foreach(Cell cell in this.Tree.HostedControlCells) { Rectangle bounds = NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds, cell, offset); Rectangle screenBounds=this.Tree.GetScreenRectangle(bounds); if(!bounds.IsEmpty && cell.HostedControl.Bounds!=screenBounds) { if(zoom!=1) { cell.HostedControlSize = bounds.Size; cell.IgnoreHostedControlSizeChange = true; } else { cell.HostedControlSize = Size.Empty; } cell.HostedControl.Bounds=screenBounds; if(zoom!=1) cell.IgnoreHostedControlSizeChange = false; if(cell.Parent!=null) { bool visible = NodeOperations.GetIsNodeVisible(cell.Parent); if(visible!=cell.HostedControl.Visible) cell.HostedControl.Visible = visible; } } } } } }