703 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			703 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Drawing;
 | 
						|
using System.Collections;
 | 
						|
using DevComponents.DotNetBar;
 | 
						|
using System.Drawing.Drawing2D;
 | 
						|
using System.Drawing.Text;
 | 
						|
using System.Collections.Generic;
 | 
						|
 | 
						|
namespace DevComponents.AdvTree.Layout
 | 
						|
{
 | 
						|
	/// <summary>
 | 
						|
	/// Summary description for NodeLayout.
 | 
						|
	/// </summary>
 | 
						|
	internal abstract class NodeLayout
 | 
						|
	{
 | 
						|
		#region Private Variables
 | 
						|
		protected int m_Height=0;
 | 
						|
		protected int m_Width=0;
 | 
						|
		protected AdvTree m_Tree=null;
 | 
						|
		protected Rectangle m_ClientArea;
 | 
						|
		//protected int m_ExpandAreaWidth=8;
 | 
						|
		protected Size m_ExpandPartSize=new Size(8,8);
 | 
						|
	    private Size _CachedExpandPartSize = Size.Empty;
 | 
						|
		private int m_CommandAreaWidth=10;
 | 
						|
		private int m_TreeLayoutChildNodeIndent = 16;
 | 
						|
 | 
						|
		private System.Windows.Forms.LeftRightAlignment m_LeftRight=System.Windows.Forms.LeftRightAlignment.Left;
 | 
						|
		private int m_NodeVerticalSpacing=3;
 | 
						|
		private int m_NodeHorizontalSpacing=0;
 | 
						|
		private CellLayout m_CellLayout=null;
 | 
						|
		private Graphics m_Graphics=null;
 | 
						|
		#endregion
 | 
						|
 | 
						|
		public NodeLayout(AdvTree treeControl, Rectangle clientArea, LayoutSettings layoutSettings)
 | 
						|
		{
 | 
						|
			m_Tree=treeControl;
 | 
						|
			m_ClientArea=clientArea;
 | 
						|
            _LayoutSettings = layoutSettings;
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Performs layout of the nodes inside of the tree control.
 | 
						|
		/// </summary>
 | 
						|
		public virtual void PerformLayout()
 | 
						|
		{
 | 
						|
		}
 | 
						|
 | 
						|
        public virtual void UpdateTopLevelColumnsWidth()
 | 
						|
        {
 | 
						|
        }
 | 
						|
 | 
						|
        private LayoutSettings _LayoutSettings;
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets layout settings.
 | 
						|
        /// </summary>
 | 
						|
        public LayoutSettings LayoutSettings
 | 
						|
        {
 | 
						|
            get { return _LayoutSettings; }
 | 
						|
            set { _LayoutSettings = value; }
 | 
						|
        }
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Performs layout for single unassigned node. Node does not have to be part of the tree control.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="node">Node to perform layout on.</param>
 | 
						|
		public virtual void PerformSingleNodeLayout(Node node)
 | 
						|
		{
 | 
						|
			if(node==null)
 | 
						|
				return;
 | 
						|
 | 
						|
			this.PrepareStyles();
 | 
						|
			// Get default Columns
 | 
						|
 | 
						|
			System.Drawing.Graphics g=this.GetGraphics();
 | 
						|
 | 
						|
            SmoothingMode sm = g.SmoothingMode;
 | 
						|
            TextRenderingHint th = g.TextRenderingHint;
 | 
						|
            if (m_Tree.AntiAlias)
 | 
						|
            {
 | 
						|
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
 | 
						|
                //g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint;
 | 
						|
            }
 | 
						|
 | 
						|
			try
 | 
						|
			{
 | 
						|
				NodeLayoutContextInfo layoutInfo=this.GetDefaultNodeLayoutContextInfo(g);
 | 
						|
				layoutInfo.ContextNode=node;
 | 
						|
			    if (node.IsDragNode)
 | 
						|
			        layoutInfo.DefaultColumns = new NodeColumnInfo(new List<ColumnInfo>(), false);
 | 
						|
				LayoutNode(layoutInfo);
 | 
						|
			}
 | 
						|
			finally
 | 
						|
			{
 | 
						|
                if (m_Tree.AntiAlias)
 | 
						|
                {
 | 
						|
                    g.SmoothingMode = sm;
 | 
						|
                    //g.TextRenderingHint = th;
 | 
						|
                }
 | 
						|
				g.Dispose();
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		public int Width
 | 
						|
		{
 | 
						|
			get {return m_Width;}
 | 
						|
		}
 | 
						|
 | 
						|
		public int Height
 | 
						|
		{
 | 
						|
			get {return m_Height;}
 | 
						|
		}
 | 
						|
 | 
						|
		public Rectangle ClientArea
 | 
						|
		{
 | 
						|
			get {return m_ClientArea;}
 | 
						|
			set {m_ClientArea=value;}
 | 
						|
		}
 | 
						|
		
 | 
						|
		public Graphics Graphics
 | 
						|
		{
 | 
						|
			get { return m_Graphics;}
 | 
						|
			set { m_Graphics = value;}
 | 
						|
		}
 | 
						|
		
 | 
						|
		internal bool DisposeGraphics
 | 
						|
		{
 | 
						|
			get
 | 
						|
			{
 | 
						|
				return (m_Graphics == null);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		protected virtual System.Drawing.Graphics GetGraphics()
 | 
						|
		{
 | 
						|
			if(m_Graphics!=null)
 | 
						|
				return m_Graphics;
 | 
						|
			
 | 
						|
			Graphics g=m_Tree.CreateGraphics();
 | 
						|
 | 
						|
			
 | 
						|
			return g;
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Resizes all styles and prepares them for layout.
 | 
						|
		/// </summary>
 | 
						|
		protected virtual void PrepareStyles()
 | 
						|
		{
 | 
						|
			// Resize styles if needed
 | 
						|
			foreach(ElementStyle es in m_Tree.Styles)
 | 
						|
			{
 | 
						|
				if(es.SizeChanged)
 | 
						|
					ElementStyleLayout.CalculateStyleSize(es,m_Tree.Font);
 | 
						|
			}
 | 
						|
 | 
						|
            if (_LayoutSettings != null)
 | 
						|
                _CachedExpandPartSize = Dpi.Size(_LayoutSettings.ExpandPartSize);
 | 
						|
            else
 | 
						|
    			_CachedExpandPartSize = Dpi.Size(m_ExpandPartSize);
 | 
						|
            
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Returns default top-level columns for tree control.
 | 
						|
		/// </summary>
 | 
						|
		/// <returns>Returns array list of ColumnInfo objects.</returns>
 | 
						|
        protected virtual NodeColumnInfo GetDefaultColumnInfo()
 | 
						|
		{
 | 
						|
            List<ColumnInfo> ci = new List<ColumnInfo>();
 | 
						|
            NodeColumnInfo info = new NodeColumnInfo(ci, false);
 | 
						|
			ColumnHeaderCollection columns=m_Tree.Columns;
 | 
						|
            //int treeWidth = m_Tree.ClientRectangle.Width;
 | 
						|
			if(columns!=null)
 | 
						|
			{
 | 
						|
                for (int i = 0; i < columns.Count; i++)
 | 
						|
				{
 | 
						|
                    int columnIndex = columns.DisplayIndexMap[i];
 | 
						|
                    ColumnHeader h = columns[columnIndex];
 | 
						|
                    ColumnInfo columnInfo = new ColumnInfo(h.Bounds.Width, h.Visible, h, columnIndex);
 | 
						|
                    ci.Add(columnInfo);
 | 
						|
                    info.HasAutoSizeColumn |= columnInfo.AutoSize;
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			return info;
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Returns column information for a given node.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="node">Node to return column information for</param>
 | 
						|
		/// <returns>Returns array list of ColumnInfo objects or null if there are no columns defined.</returns>
 | 
						|
		protected virtual NodeColumnInfo GetNodeColumnInfo(Node node)
 | 
						|
		{
 | 
						|
            if (!node.HasColumns)
 | 
						|
            {
 | 
						|
                return null;
 | 
						|
            }
 | 
						|
 | 
						|
            List<ColumnInfo> ci = new List<ColumnInfo>();
 | 
						|
            NodeColumnInfo info = new NodeColumnInfo(ci, false);
 | 
						|
            ColumnHeaderCollection columns = node.NodesColumns;
 | 
						|
            for (int i = 0; i < columns.Count; i++)
 | 
						|
			{
 | 
						|
                int columnIndex = columns.DisplayIndexMap[i];
 | 
						|
                ColumnHeader h = columns[columnIndex];
 | 
						|
                ColumnInfo columnInfo = new ColumnInfo(h.Bounds.Width, h.Visible, h, columnIndex);
 | 
						|
                ci.Add(columnInfo);
 | 
						|
                info.HasAutoSizeColumn |= columnInfo.AutoSize;
 | 
						|
			}
 | 
						|
 | 
						|
            return info;
 | 
						|
		}
 | 
						|
 | 
						|
        ///// <summary>
 | 
						|
        ///// Gets or sets the vertical spacing between nodes in pixels.
 | 
						|
        ///// </summary>
 | 
						|
        //public virtual int NodeVerticalSpacing
 | 
						|
        //{
 | 
						|
        //    get {return m_NodeVerticalSpacing;}
 | 
						|
        //    set {m_NodeVerticalSpacing=value;}
 | 
						|
        //}
 | 
						|
 | 
						|
        ///// <summary>
 | 
						|
        ///// Gets or sets the horizontal spacing between nodes in pixels.
 | 
						|
        ///// </summary>
 | 
						|
        //public virtual int NodeHorizontalSpacing
 | 
						|
        //{
 | 
						|
        //    get {return m_NodeHorizontalSpacing;}
 | 
						|
        //    set {m_NodeHorizontalSpacing=value;}
 | 
						|
        //}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Gets or sets the child node indent in pixels.
 | 
						|
		/// </summary>
 | 
						|
		public virtual int TreeLayoutChildNodeIndent
 | 
						|
		{
 | 
						|
			get {return m_TreeLayoutChildNodeIndent; }
 | 
						|
			set { m_TreeLayoutChildNodeIndent = value; }
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Returns column header collection for the given column template name.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="name">Name of the column template.</param>
 | 
						|
		/// <returns>Column header collection or null if template name cannot be found.</returns>
 | 
						|
		public virtual ColumnHeaderCollection GetColumnHeader(string name)
 | 
						|
		{
 | 
						|
			if(name=="" || name==null)
 | 
						|
				return null;
 | 
						|
			return m_Tree.Headers.GetByName(name).Columns;
 | 
						|
		}
 | 
						|
 | 
						|
        //private int _ExpandAreaWidth = 24;
 | 
						|
        ///// <summary>
 | 
						|
        ///// Returns width of the expand button area. Default is 24 pixels.
 | 
						|
        ///// </summary>
 | 
						|
        //public virtual int ExpandAreaWidth
 | 
						|
        //{
 | 
						|
        //    get { return _ExpandAreaWidth; }
 | 
						|
        //    set
 | 
						|
        //    {
 | 
						|
        //        _ExpandAreaWidth = value;
 | 
						|
        //    }
 | 
						|
        //}
 | 
						|
 | 
						|
        ///// <summary>
 | 
						|
        ///// Gets or sets width of command button area. Default is 8 pixels.
 | 
						|
        ///// </summary>
 | 
						|
        //public virtual int CommandAreaWidth
 | 
						|
        //{
 | 
						|
        //    get {return m_CommandAreaWidth;}
 | 
						|
        //    set {m_CommandAreaWidth=value;}
 | 
						|
        //}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Sets the position and size of the node command button.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="layoutInfo">Node layout context information</param>
 | 
						|
		protected virtual void LayoutCommandPart(NodeLayoutContextInfo layoutInfo, ElementStyle nodeStyle)
 | 
						|
		{
 | 
						|
			// Command part is right-aligned just before the node border
 | 
						|
            Rectangle bounds = new Rectangle(layoutInfo.ContextNode.ContentBounds.Right - this.LayoutSettings.CommandAreaWidth -
 | 
						|
				ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Right),layoutInfo.ContextNode.ContentBounds.Y+
 | 
						|
				ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Top),
 | 
						|
                this.LayoutSettings.CommandAreaWidth, layoutInfo.ContextNode.ContentBounds.Height -
 | 
						|
				ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Top)-
 | 
						|
				ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Bottom));
 | 
						|
//			Rectangle bounds=new Rectangle(layoutInfo.ContextNode.ContentBounds.Right-this.CommandAreaWidth-
 | 
						|
//				ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Right),layoutInfo.ContextNode.ContentBounds.Y, 
 | 
						|
//				this.CommandAreaWidth, layoutInfo.ContextNode.ContentBounds.Height);
 | 
						|
			layoutInfo.ContextNode.CommandBoundsRelative=bounds;
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Determines the rectangle of the +/- part of the tree node that is used to expand node.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="layoutInfo">Node layout context information</param>
 | 
						|
		protected virtual void LayoutExpandPart(NodeLayoutContextInfo layoutInfo, bool bLeftNode, int x)
 | 
						|
		{
 | 
						|
			Node node=layoutInfo.ContextNode;
 | 
						|
 | 
						|
			Size partSize=GetExpandPartSize();
 | 
						|
 | 
						|
			Rectangle bounds=new Rectangle(x,0,partSize.Width,partSize.Height);
 | 
						|
 | 
						|
            if (node.ExpandPartVerticalAlignment == eVerticalAlign.Middle)
 | 
						|
                bounds.Y = (node.BoundsRelative.Height - bounds.Height) / 2;
 | 
						|
            else if (node.ExpandPartVerticalAlignment == eVerticalAlign.Top)
 | 
						|
                bounds.Y = Dpi.Height3;
 | 
						|
            else
 | 
						|
                bounds.Y = node.BoundsRelative.Height - partSize.Height - Dpi.Height3;
 | 
						|
 | 
						|
            if (bLeftNode || layoutInfo.ExpandPartAlignedLeft && layoutInfo.LeftToRight)
 | 
						|
                bounds.X += (layoutInfo.ExpandAreaWidth - bounds.Width) / 2;
 | 
						|
            else
 | 
						|
                bounds.X = node.BoundsRelative.Right - layoutInfo.ExpandAreaWidth + (layoutInfo.ExpandAreaWidth - partSize.Width) / 2;
 | 
						|
 | 
						|
			node.SetExpandPartRectangle(bounds);
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Returns the size of the node expand part.
 | 
						|
		/// </summary>
 | 
						|
		/// <returns>Size of the expand part, default 8,8.</returns>
 | 
						|
		protected virtual Size GetExpandPartSize()
 | 
						|
		{
 | 
						|
            return _CachedExpandPartSize;
 | 
						|
            //if (_LayoutSettings != null)
 | 
						|
            //    return _LayoutSettings.ExpandPartSize;
 | 
						|
            //return m_ExpandPartSize;
 | 
						|
		}
 | 
						|
 | 
						|
        ///// <summary>
 | 
						|
        ///// Gets or sets the size of the expand part that is expanding/collapsing the node. Default value is 8,8.
 | 
						|
        ///// </summary>
 | 
						|
        //public System.Drawing.Size ExpandPartSize
 | 
						|
        //{
 | 
						|
        //    get {return m_ExpandPartSize;}
 | 
						|
        //    set {m_ExpandPartSize=value;}
 | 
						|
        //}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Provides the layout for single node.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="layoutInfo">Layout information.</param>
 | 
						|
		protected virtual void LayoutNode(NodeLayoutContextInfo layoutInfo)
 | 
						|
		{
 | 
						|
			bool bHasExpandPart=this.HasExpandPart(layoutInfo);
 | 
						|
			bool bHasCommandPart=this.HasCommandPart(layoutInfo);
 | 
						|
 | 
						|
			Node node=layoutInfo.ContextNode;
 | 
						|
 | 
						|
            Rectangle nodeRect = new Rectangle(layoutInfo.Left, layoutInfo.Top, 0, 0);
 | 
						|
			Rectangle nodeContentRect=Rectangle.Empty; // Node content rect excludes expand rect
 | 
						|
 | 
						|
			int height=0, width=0;
 | 
						|
			
 | 
						|
			// Left node relative to the main root node...
 | 
						|
            bool bLeftNode = layoutInfo.LeftToRight; // (layoutInfo.MapPositionNear && layoutInfo.LeftToRight);
 | 
						|
            layoutInfo.LayoutNodeExpandPartWidth = 0;
 | 
						|
			if(bLeftNode && bHasExpandPart || this.ReserveExpandPartSpace)
 | 
						|
			{
 | 
						|
                layoutInfo.LayoutNodeExpandPartWidth = (layoutInfo.ExpandAreaWidth + this.GetCellLayout().CellPartSpacing);
 | 
						|
                width += (layoutInfo.ExpandAreaWidth + this.GetCellLayout().CellPartSpacing);
 | 
						|
			}
 | 
						|
 | 
						|
			int x=width;		// relative to 0,0 of the node
 | 
						|
			int y=0;			// Relative to 0,0 of the node
 | 
						|
			
 | 
						|
			// Apply node style
 | 
						|
			ElementStyle nodeStyle=null;
 | 
						|
			if(node.Expanded && node.StyleExpanded!=null)
 | 
						|
				nodeStyle=node.StyleExpanded;
 | 
						|
			else if(node.Style!=null)
 | 
						|
				nodeStyle=node.Style;
 | 
						|
			else
 | 
						|
				nodeStyle=layoutInfo.DefaultNodeStyle;
 | 
						|
 | 
						|
			nodeContentRect.X=x;
 | 
						|
 | 
						|
			if(nodeStyle!=null)
 | 
						|
			{
 | 
						|
				x+=ElementStyleLayout.LeftWhiteSpace(nodeStyle);
 | 
						|
				y+=ElementStyleLayout.TopWhiteSpace(nodeStyle);
 | 
						|
				nodeContentRect.X+=nodeStyle.MarginLeft;
 | 
						|
				nodeContentRect.Y+=nodeStyle.MarginTop;
 | 
						|
			}
 | 
						|
 | 
						|
            Size size = this.GetCellLayout().LayoutCells(layoutInfo, x, y);
 | 
						|
 | 
						|
            node.SetCellsBounds(new Rectangle(x, y, size.Width, size.Height));
 | 
						|
 | 
						|
			height=size.Height;
 | 
						|
			width+=size.Width;
 | 
						|
 | 
						|
			nodeContentRect.Width=size.Width;
 | 
						|
			nodeContentRect.Height=size.Height;
 | 
						|
 | 
						|
			if(nodeStyle!=null)
 | 
						|
			{
 | 
						|
				nodeContentRect.Width+=(ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Left)+
 | 
						|
					ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Right));
 | 
						|
				nodeContentRect.Height+=(ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Top)+
 | 
						|
					ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Padding | eSpacePart.Border,eStyleSide.Bottom));
 | 
						|
 | 
						|
				width+=(ElementStyleLayout.HorizontalStyleWhiteSpace(nodeStyle));
 | 
						|
				height+=(ElementStyleLayout.VerticalStyleWhiteSpace(nodeStyle));
 | 
						|
			}
 | 
						|
 | 
						|
            if (!bLeftNode && bHasExpandPart && !this.ReserveExpandPartSpace)
 | 
						|
                width += layoutInfo.ExpandAreaWidth;
 | 
						|
 | 
						|
			if(bHasCommandPart)
 | 
						|
			{
 | 
						|
                width += this.LayoutSettings.CommandAreaWidth;
 | 
						|
                nodeContentRect.Width += this.LayoutSettings.CommandAreaWidth;
 | 
						|
			}
 | 
						|
 | 
						|
			nodeRect.Height=height;
 | 
						|
			nodeRect.Width=width;
 | 
						|
			node.SetBounds(nodeRect);
 | 
						|
			node.SetContentBounds(nodeContentRect);
 | 
						|
 | 
						|
			if(bHasCommandPart)
 | 
						|
				LayoutCommandPart(layoutInfo, nodeStyle);
 | 
						|
			else
 | 
						|
				node.CommandBoundsRelative=Rectangle.Empty;
 | 
						|
 | 
						|
            if (bHasExpandPart || this.ReserveExpandPartSpace)
 | 
						|
				LayoutExpandPart(layoutInfo,bLeftNode, 0);
 | 
						|
			else
 | 
						|
				node.SetExpandPartRectangle(Rectangle.Empty);
 | 
						|
 | 
						|
			node.SizeChanged=false;
 | 
						|
 | 
						|
			// Calculate size and location of node column header if any
 | 
						|
			//if(node.NodesColumnHeaderVisible)
 | 
						|
			{
 | 
						|
				//layoutInfo.Left+=this.NodeLevelOffset;
 | 
						|
				LayoutColumnHeader(layoutInfo);
 | 
						|
				//layoutInfo.Left-=this.NodeLevelOffset;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Returns true if given node has expand part.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="layoutInfo">Layout context information.</param>
 | 
						|
		/// <returns></returns>
 | 
						|
		protected virtual bool HasExpandPart(NodeLayoutContextInfo layoutInfo)
 | 
						|
		{
 | 
						|
			Node node=layoutInfo.ContextNode;
 | 
						|
			if(node.ExpandVisibility==eNodeExpandVisibility.Auto)
 | 
						|
			{
 | 
						|
				if(IsRootNode(node) && !RootHasExpandedPart || !NodeOperations.GetAnyVisibleNodes(node))
 | 
						|
					return false;
 | 
						|
				return true;
 | 
						|
			}
 | 
						|
			else
 | 
						|
				return (node.ExpandVisibility==eNodeExpandVisibility.Visible);
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Returns whether given node has command part.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="layoutInfo">Layout context information.</param>
 | 
						|
		/// <returns>True if command part should be drawn otherwise false.</returns>
 | 
						|
		protected virtual bool HasCommandPart(NodeLayoutContextInfo layoutInfo)
 | 
						|
		{
 | 
						|
			return layoutInfo.ContextNode.CommandButton;
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Returns true if root node should have expanded part
 | 
						|
		/// </summary>
 | 
						|
		protected virtual bool RootHasExpandedPart
 | 
						|
		{
 | 
						|
			get {return true;}
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Returns true if expand part space should be accounted for even if they expand part is not visible or need to be displayed. Default value is false.
 | 
						|
		/// </summary>
 | 
						|
		protected virtual bool ReserveExpandPartSpace
 | 
						|
		{
 | 
						|
			get
 | 
						|
			{
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Returns class responsible for cell layout.
 | 
						|
		/// </summary>
 | 
						|
		/// <returns>Cell layout class.</returns>
 | 
						|
		protected internal virtual CellLayout GetCellLayout()
 | 
						|
		{
 | 
						|
            if (m_CellLayout == null)
 | 
						|
                m_CellLayout = new CellLayout(this.LayoutSettings);
 | 
						|
			return m_CellLayout;
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Offsets node location and location of it's child nodes bounds.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name="node">Node to offset.</param>
 | 
						|
		/// <param name="x">Horizontal offset.</param>
 | 
						|
		/// <param name="y">Vertical offset.</param>
 | 
						|
		protected virtual void OffsetNodeLocation(Node node, int x, int y)
 | 
						|
		{
 | 
						|
			node.SetBounds(new Rectangle(node.BoundsRelative.X+x,node.BoundsRelative.Y+y,node.BoundsRelative.Width,node.BoundsRelative.Height));
 | 
						|
			if(node.Expanded)
 | 
						|
				node.ChildNodesBounds=new Rectangle(node.ChildNodesBounds.X+x,node.ChildNodesBounds.Y+y,node.ChildNodesBounds.Width,node.ChildNodesBounds.Height);
 | 
						|
		}
 | 
						|
 | 
						|
		protected virtual NodeLayoutContextInfo GetDefaultNodeLayoutContextInfo(System.Drawing.Graphics graphics)
 | 
						|
		{
 | 
						|
			NodeLayoutContextInfo layoutInfo=new NodeLayoutContextInfo();
 | 
						|
			layoutInfo.ClientRectangle=m_ClientArea;
 | 
						|
			layoutInfo.DefaultColumns=this.GetDefaultColumnInfo();
 | 
						|
			layoutInfo.ChildColumns=null;
 | 
						|
            layoutInfo.Indent = m_Tree.Indent;
 | 
						|
			layoutInfo.Left=0;
 | 
						|
			layoutInfo.Top=0;
 | 
						|
		    layoutInfo.LeftMargin = m_Tree.BackgroundStyle.PaddingLeft;
 | 
						|
			layoutInfo.DefaultFont=m_Tree.Font;
 | 
						|
			layoutInfo.LeftToRight=(this.LeftRight==System.Windows.Forms.LeftRightAlignment.Left);
 | 
						|
			layoutInfo.Graphics=graphics;
 | 
						|
			layoutInfo.Styles=m_Tree.Styles;
 | 
						|
            layoutInfo.FullRowBackgroundNodes = new ArrayList();
 | 
						|
			if(m_Tree.CellLayout!=eCellLayout.Default)
 | 
						|
				layoutInfo.CellLayout=m_Tree.CellLayout;
 | 
						|
			if(m_Tree.CellPartLayout!=eCellPartLayout.Default)
 | 
						|
				layoutInfo.CellPartLayout=m_Tree.CellPartLayout;
 | 
						|
				
 | 
						|
			if(m_Tree.NodeStyle!=null)
 | 
						|
				layoutInfo.DefaultNodeStyle=m_Tree.NodeStyle;
 | 
						|
 | 
						|
			if(m_Tree.CellStyleDefault!=null)
 | 
						|
				layoutInfo.DefaultCellStyle=m_Tree.CellStyleDefault;
 | 
						|
			else
 | 
						|
				layoutInfo.DefaultCellStyle=ElementStyle.GetDefaultCellStyle(layoutInfo.DefaultNodeStyle);
 | 
						|
 | 
						|
			// Determine size of the default Column Header
 | 
						|
			if(m_Tree.ColumnStyleNormal!=null)
 | 
						|
			{
 | 
						|
				ElementStyleLayout.CalculateStyleSize(m_Tree.ColumnStyleNormal,layoutInfo.DefaultFont);
 | 
						|
				layoutInfo.DefaultHeaderSize=m_Tree.ColumnStyleNormal.Size;
 | 
						|
			}
 | 
						|
 | 
						|
			if(layoutInfo.DefaultHeaderSize.IsEmpty)
 | 
						|
				layoutInfo.DefaultHeaderSize.Height=layoutInfo.DefaultFont.Height+4;
 | 
						|
 | 
						|
            layoutInfo.ExpandPartWidth = Dpi.Width(this.Tree.ExpandWidth);
 | 
						|
            layoutInfo.View = this.Tree.View;
 | 
						|
            layoutInfo.TileSize = Dpi.Size(this.Tree.TileSize);
 | 
						|
            layoutInfo.ColumnStyle = this.Tree.ColumnStyleNormal;
 | 
						|
		    layoutInfo.ExpandAreaWidth = Dpi.Width(this.LayoutSettings.ExpandAreaWidth);
 | 
						|
			return layoutInfo;
 | 
						|
		}
 | 
						|
 | 
						|
		protected Node[] GetTopLevelNodes()
 | 
						|
		{
 | 
						|
			if(m_Tree.DisplayRootNode!=null)
 | 
						|
				return new Node[] {m_Tree.DisplayRootNode};
 | 
						|
			else
 | 
						|
			{
 | 
						|
				Node[] nodes=new Node[m_Tree.Nodes.Count];
 | 
						|
				m_Tree.Nodes.CopyTo(nodes);
 | 
						|
				return nodes;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		protected bool IsRootNode(Node node)
 | 
						|
		{
 | 
						|
			return NodeOperations.IsRootNode(m_Tree,node);
 | 
						|
		}
 | 
						|
 | 
						|
		protected virtual void EmptyBoundsUnusedNodes(Node[] topLevelNodes)
 | 
						|
		{
 | 
						|
			if(m_Tree.DisplayRootNode!=null)
 | 
						|
			{
 | 
						|
				Node node=m_Tree.DisplayRootNode.PrevVisibleNode;
 | 
						|
				while(node!=null)
 | 
						|
				{
 | 
						|
					node.SetBounds(Rectangle.Empty);
 | 
						|
					node=node.PrevVisibleNode;
 | 
						|
				}
 | 
						|
				node=m_Tree.DisplayRootNode.NextNode;
 | 
						|
				if(node==null)
 | 
						|
				{
 | 
						|
					node=m_Tree.DisplayRootNode.Parent;
 | 
						|
					while(node!=null)
 | 
						|
					{
 | 
						|
						if(node.NextNode!=null)
 | 
						|
						{
 | 
						|
							node=node.NextNode;
 | 
						|
							break;
 | 
						|
						}
 | 
						|
						else
 | 
						|
							node=node.Parent;
 | 
						|
					}
 | 
						|
				}
 | 
						|
				while(node!=null)
 | 
						|
				{
 | 
						|
					node.SetBounds(Rectangle.Empty);
 | 
						|
					node=node.NextVisibleNode;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				for(int i=1;i<topLevelNodes.Length;i++)
 | 
						|
				{
 | 
						|
					topLevelNodes[i].SetBounds(Rectangle.Empty);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
        public AdvTree Tree
 | 
						|
        {
 | 
						|
            get { return m_Tree; }
 | 
						|
        }
 | 
						|
 | 
						|
        
 | 
						|
 | 
						|
		#region Column Support
 | 
						|
		// Assumes that layoutInfo is up-to-date and that Node that is connected with
 | 
						|
		// columns is already processed and it's size and location calculated.
 | 
						|
		// layoutInfo.Top member reflects the next position below the node
 | 
						|
		// layoutInfo.LevelOffset should reflect the X offset for the child nodes.
 | 
						|
		public void LayoutColumnHeader(NodeLayoutContextInfo layoutInfo)
 | 
						|
		{
 | 
						|
			Node node=layoutInfo.ContextNode;
 | 
						|
 | 
						|
            if (!node.HasColumns || !node.Expanded)
 | 
						|
            {
 | 
						|
                node.ColumnHeaderHeight = 0;
 | 
						|
                return;
 | 
						|
            }
 | 
						|
            int spacing = 2;
 | 
						|
            int x = layoutInfo.Left + this.NodeLevelOffset + node.NodesIndent;
 | 
						|
			int y=layoutInfo.ContextNode.BoundsRelative.Bottom + spacing;
 | 
						|
 | 
						|
			bool bLeftNode=(layoutInfo.MapPositionNear && layoutInfo.LeftToRight);
 | 
						|
            int expandPartWidth = layoutInfo.ExpandAreaWidth;
 | 
						|
			int cellPartSpacing=GetCellLayout().CellPartSpacing;
 | 
						|
 | 
						|
            if (!bLeftNode)
 | 
						|
                x += (expandPartWidth + cellPartSpacing);
 | 
						|
 | 
						|
            int clientWidth = layoutInfo.ClientRectangle.Width - (layoutInfo.Left + expandPartWidth);
 | 
						|
            if (clientWidth <= 0)
 | 
						|
                clientWidth = layoutInfo.ClientRectangle.Width;
 | 
						|
 | 
						|
            node.ColumnHeaderHeight = Layout.ColumnHeaderLayout.LayoutColumnHeader(layoutInfo, x, y, clientWidth, this.GetCellLayout().LayoutSettings.CellHorizontalSpacing) + spacing;
 | 
						|
            if (!node.NodesColumnsHeaderVisible)
 | 
						|
                node.ColumnHeaderHeight = 0;
 | 
						|
		}
 | 
						|
 | 
						|
        private int _NodeLevelOffset = 16;
 | 
						|
        internal int NodeLevelOffset
 | 
						|
        {
 | 
						|
            get { return _NodeLevelOffset; }
 | 
						|
            set
 | 
						|
            {
 | 
						|
                _NodeLevelOffset = value;
 | 
						|
            }
 | 
						|
        }
 | 
						|
		#endregion
 | 
						|
		
 | 
						|
		#region RTL Support
 | 
						|
		public virtual System.Windows.Forms.LeftRightAlignment LeftRight
 | 
						|
		{
 | 
						|
			get {return m_LeftRight;}
 | 
						|
			set {m_LeftRight=value;}
 | 
						|
		}
 | 
						|
		#endregion
 | 
						|
	}
 | 
						|
 | 
						|
    internal class NodeColumnInfo
 | 
						|
    {
 | 
						|
        /// <summary>
 | 
						|
        /// Initializes a new instance of the NodeColumnInfo structure.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="columnInfo"></param>
 | 
						|
        /// <param name="hasAutoSizeColumn"></param>
 | 
						|
        public NodeColumnInfo(List<ColumnInfo> columnInfo, bool hasAutoSizeColumn)
 | 
						|
        {
 | 
						|
            ColumnInfo = columnInfo;
 | 
						|
            HasAutoSizeColumn = hasAutoSizeColumn;
 | 
						|
        }
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets the list of column info object for the columns.
 | 
						|
        /// </summary>
 | 
						|
        public List<ColumnInfo> ColumnInfo;
 | 
						|
        /// <summary>
 | 
						|
        /// Gets or sets whether columns have auto-size column.
 | 
						|
        /// </summary>
 | 
						|
        public bool HasAutoSizeColumn;
 | 
						|
    }
 | 
						|
}
 |