DotNet 4.8.1 build of DotNetBar

This commit is contained in:
2025-02-07 10:35:23 -05:00
parent 33439b63a0
commit 6b0a5d60f4
2609 changed files with 989814 additions and 7 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="ResMimeType">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="Version">
<value>1.0.0.0</value>
</resheader>
<resheader name="Reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="Writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,171 @@
using System;
using System.Collections;
using System.ComponentModel;
namespace DevComponents.Tree
{
///<summary>
/// A strongly-typed collection of <see cref="Cell"/> objects.
///</summary>
public class CellCollection:CollectionBase
{
#region Private Variables
private Node m_ParentNode=null;
#endregion
#region Internal Implementation
/// <summary>Creates new instance of the class.</summary>
public CellCollection()
{
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="cell">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(Cell cell)
{
return List.Add(cell);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public Cell this[int index]
{
get {return (Cell)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, Cell value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(Cell value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(Cell value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(Cell value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
Cell cell=value as Cell;
cell.SetParent(null);
if(m_ParentNode!=null)
m_ParentNode.OnCellRemoved(cell);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
Cell cell=value as Cell;
if(cell.Parent!=null && cell.Parent!=m_ParentNode)
cell.Parent.Cells.Remove(cell);
cell.SetParent(m_ParentNode);
if(m_ParentNode!=null)
m_ParentNode.OnCellInserted(cell);
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(Cell[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the Cell array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(Cell[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
base.OnClear();
}
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Node ParentNode
{
get {return m_ParentNode;}
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">Cell that is parent of this collection.</param>
internal void SetParentNode(Node parent)
{
m_ParentNode=parent;
}
#endregion
}
#region CellCollectionEditor
/// <summary>
/// Support for Cell tabs design-time editor.
/// </summary>
public class CellCollectionEditor:System.ComponentModel.Design.CollectionEditor
{
/// <summary>Creates new instance of cell collection editor.</summary>
/// <param name="type">Type to initialize editor with.</param>
public CellCollectionEditor(Type type):base(type)
{
}
protected override Type CreateCollectionItemType()
{
return typeof(Cell);
}
protected override Type[] CreateNewItemTypes()
{
return new Type[] {typeof(Cell)};
}
protected override object CreateInstance(Type itemType)
{
object item=base.CreateInstance(itemType);
if(item is Cell)
{
Cell cell=item as Cell;
cell.Text=cell.Name;
}
return item;
}
}
#endregion
}

View File

@@ -0,0 +1,44 @@
using System;
namespace DevComponents.Tree
{
/// <summary>
/// Represents event arguments for cell editing events.
/// </summary>
public class CellEditEventArgs
{
/// <summary>
/// Indicates the action that caused the event.
/// </summary>
public eTreeAction Action=eTreeAction.Code;
/// <summary>
/// Indicates the cell that is affected.
/// </summary>
public DevComponents.Tree.Cell Cell=null;
/// <summary>
/// Indicates new text that will be assigned to the cell if one is appropriate for given event.
/// </summary>
public string NewText="";
/// <summary>
/// Indicates whether the current action is cancelled. For BeforeCellEdit event setting this
/// property to true will cancel the editing. For AfterCellEdit event setting this property to
/// true will cancel any changes made to the text and edits will not be accepted. For CellEditEnding
/// event setting this property to true will keep the cell in edit mode.
/// </summary>
public bool Cancel=false;
/// <summary>
/// Initializes new instance of CellEditEventArgs class.
/// </summary>
/// <param name="cell">Reference to Cell this event is raised for.</param>
/// <param name="action">Indicates the action that caused the event.</param>
/// <param name="newText">Indicates new text of the cell if it applies to given event.</param>
public CellEditEventArgs(Cell cell, eTreeAction action, string newText)
{
this.Action=action;
this.Cell=cell;
this.NewText=newText;
}
}
}

View File

@@ -0,0 +1,375 @@
using System;
using System.Drawing;
using System.ComponentModel;
namespace DevComponents.Tree
{
/// <summary>
/// Represents class that holds images for a cell.
/// </summary>
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writting .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
[ToolboxItem(false), TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
public class CellImages
{
// Image variables
private System.Drawing.Image m_Image=null;
private int m_ImageIndex=-1; // Image index if image from ImageList is used
private System.Drawing.Image m_ImageMouseOver=null;
private int m_ImageMouseOverIndex=-1; // Image index if image from ImageList is used
// private System.Drawing.Image m_ImageDisabled=null;
// private bool m_DisabledImageCustom=false;
// private int m_ImageDisabledIndex=-1; // Image index if image from ImageList is used
private System.Drawing.Image m_ImageExpanded=null;
private int m_ImageExpandedIndex=-1;
private Cell m_ParentCell=null;
private Size m_LargestImageSize=Size.Empty;
/// <summary>
/// Initializes new instance of CellImages class.
/// </summary>
/// <param name="parentCell">Reference to parent cell.</param>
public CellImages(Cell parentCell)
{
m_ParentCell=parentCell;
}
#region Properties
/// <summary>
/// Gets or sets default cell image. Setting this property to valid image will
/// override any setting of ImageIndex property.
/// </summary>
/// <remarks>
/// <para>The image set through this property will be serialized with the cell. If you
/// plan to use ImageList then use <see cref="ImageIndex">ImageIndex</see>
/// property.</para>
/// <para>
/// <para>If you plan to use alpha-blended images we recommend using PNG-24 format
/// which supports alpha-blending. As of this writting .NET Framework 1.0 and 1.1
/// do not support alpha-blending when used through Image class.</para>
/// </para>
/// </remarks>
/// <value>Image object or <strong>null (Nothing)</strong> if no image is assigned.</value>
[Browsable(true),DefaultValue(null),Category("Images"),Description("Indicates default cell image"), DevCoSerialize()]
public System.Drawing.Image Image
{
get {return m_Image;}
set
{
m_Image=value;
this.OnImageChanged();
}
}
/// <summary>
/// Resets Image property to it's default value (null, VB nothing).
/// </summary>
public void ResetImage()
{
TypeDescriptor.GetProperties(this)["Image"].SetValue(this, null);
}
/// <summary>
/// Gets or sets the image that is displayed when mouse is over the cell. Setting
/// this property to valid image will override any setting of ImageMouseOverIndex
/// property.
/// </summary>
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writting .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
[Browsable(true),DefaultValue(null),Category("Images"),Description("Indicates cell image when mouse is over the cell"), DevCoSerialize()]
public System.Drawing.Image ImageMouseOver
{
get {return m_ImageMouseOver;}
set
{
m_ImageMouseOver=value;
this.OnImageChanged();
}
}
/// <summary>
/// Resets ImageMouseOver to it's default value (null, VB nothing).
/// </summary>
public void ResetImageMouseOver()
{
TypeDescriptor.GetProperties(this)["ImageMouseOver"].SetValue(this, null);
}
// /// <summary>
// /// Gets or sets the image that is displayed when cell is disabled. If not assigned
// /// disabled image is created from default cell image. Setting this property to valid image
// /// will override any setting of ImageDisabledIndex property.
// /// </summary>
// /// <remarks>
// /// If you plan to use alpha-blended images we recommend using PNG-24 format which
// /// supports alpha-blending. As of this writting .NET Framework 1.0 and 1.1 do not support
// /// alpha-blending when used through Image class.
// /// </remarks>
// [Browsable(true),DefaultValue(null),Category("Images"),Description("Indicates disabled cell image")]
// public System.Drawing.Image ImageDisabled
// {
// get {return m_ImageDisabled;}
// set
// {
// m_ImageDisabled=value;
// this.OnImageChanged();
// }
// }
//
// /// <summary>
// /// Resets ImageDisabled to it's default value (null, VB nothing).
// /// </summary>
// public void ResetImageDisabled()
// {
// this.ImageDisabled=null;
// }
/// <summary>
/// Gets or sets image that is displayed when Node that this cell belongs to is
/// expanded. Setting this property to valid image will override any setting of
/// ImageExpandedIndex property.
/// </summary>
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writting .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
[Browsable(true),DefaultValue(null),Category("Images"),Description("Indicates cell image when node associtaed with this cell is expanded"), DevCoSerialize()]
public System.Drawing.Image ImageExpanded
{
get {return m_ImageExpanded;}
set
{
m_ImageExpanded=value;
this.OnImageChanged();
}
}
/// <summary>
/// Resets ImageExpanded to it's default value (null, VB nothing).
/// </summary>
public void ResetImageExpanded()
{
TypeDescriptor.GetProperties(this)["ImageExpanded"].SetValue(this, null);
}
/// <summary>
/// Gets or sets the Index of default cell image from ImageList specified on TreeGX
/// control.
/// </summary>
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writting .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
[Browsable(true),DefaultValue(-1),Category("ImageList Images"),Description("Indicates default cell image"), DevCoSerialize()]
public int ImageIndex
{
get {return m_ImageIndex;}
set
{
m_ImageIndex=value;
this.OnImageChanged();
}
}
/// <summary>
/// Property Editor support for ImageIndex selection
/// </summary>
[System.ComponentModel.Browsable(false),System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public System.Windows.Forms.ImageList ImageList
{
get
{
if(this.Parent!=null)
{
TreeGX tree=this.Parent.TreeControl;
if(tree!=null)
{
return tree.ImageList;
}
}
return null;
}
}
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writting .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
/// <summary>
/// Gets or sets the Index of cell image when mouse is over the cell from ImageList
/// specified on TreeGX control.
/// </summary>
[Browsable(true),DefaultValue(-1),Category("ImageList Images"),Description("Indicates cell image when mouse is over the cell"), DevCoSerialize()]
public int ImageMouseOverIndex
{
get {return m_ImageMouseOverIndex;}
set
{
m_ImageMouseOverIndex=value;
this.OnImageChanged();
}
}
// /// <remarks>
// /// If you plan to use alpha-blended images we recommend using PNG-24 format which
// /// supports alpha-blending. As of this writting .NET Framework 1.0 and 1.1 do not support
// /// alpha-blending when used through Image class.
// /// </remarks>
// /// <summary>
// /// Gets or sets the Index of disabled cell image from ImageList specified on TreeGX
// /// control.
// /// </summary>
// [Browsable(true),DefaultValue(-1),Category("ImageList Images"),Description("Indicates disabled cell image")]
// public int ImageDisabledIndex
// {
// get {return m_ImageDisabledIndex;}
// set
// {
// m_ImageDisabledIndex=value;
// this.OnImageChanged();
// }
// }
/// <remarks>
/// If you plan to use alpha-blended images we recommend using PNG-24 format which
/// supports alpha-blending. As of this writting .NET Framework 1.0 and 1.1 do not support
/// alpha-blending when used through Image class.
/// </remarks>
/// <summary>
/// Gets or sets the Index of cell image from ImageList specified on TreeGX control
/// that is used when Node associated with this cell is expanded
/// </summary>
[Browsable(true),DefaultValue(-1),Category("ImageList Images"),Description("Indicates expanded cell image"), DevCoSerialize()]
public int ImageExpandedIndex
{
get {return m_ImageExpandedIndex;}
set
{
m_ImageExpandedIndex=value;
this.OnImageChanged();
}
}
/// <summary>
/// Gets or sets the parent node of the cell.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Cell Parent
{
get {return m_ParentCell;}
set {m_ParentCell=value;}
}
/// <summary>
/// Gets whether CellImages object should be serialized or not. If object has all
/// default values then this property will return <strong>false</strong>.
/// </summary>
internal bool ShouldSerialize
{
get
{
if(m_Image==null && /*m_ImageDisabled==null && m_ImageDisabledIndex==-1 &&*/
m_ImageExpanded==null && m_ImageExpandedIndex==-1 && m_ImageIndex==-1 &&
m_ImageMouseOver==null && m_ImageMouseOverIndex==-1)
return false;
return true;
}
}
/// <summary>
/// Returns largest image size in this set of images.
/// </summary>
internal Size LargestImageSize
{
get
{
return m_LargestImageSize;
}
}
#endregion
#region Methods
/// <summary>Makes a copy of a CellImages object.</summary>
public virtual CellImages Copy()
{
CellImages ci=new CellImages(null);
ci.Image=this.Image;
// ci.ImageDisabled=this.ImageDisabled;
// ci.ImageDisabledIndex=this.ImageDisabledIndex;
ci.ImageExpanded=this.ImageExpanded;
ci.ImageExpandedIndex=this.ImageExpandedIndex;
ci.ImageIndex=this.ImageIndex;
ci.ImageMouseOver=this.ImageMouseOver;
ci.ImageMouseOverIndex=this.ImageMouseOverIndex;
return ci;
}
#endregion
#region Internals
private void OnImageChanged()
{
RefreshLargestImageSize();
if(this.Parent!=null)
this.Parent.OnImageChanged();
}
private void RefreshLargestImageSize()
{
m_LargestImageSize=Size.Empty;
AdjustSize(m_Image,ref m_LargestImageSize);
// AdjustSize(m_ImageDisabled,ref m_LargestImageSize);
AdjustSize(m_ImageExpanded,ref m_LargestImageSize);
AdjustSize(m_ImageMouseOver,ref m_LargestImageSize);
AdjustSize(GetImageByIndex(m_ImageIndex),ref m_LargestImageSize);
// AdjustSize(GetImageByIndex(m_ImageDisabledIndex),ref m_LargestImageSize);
AdjustSize(GetImageByIndex(m_ImageExpandedIndex),ref m_LargestImageSize);
AdjustSize(GetImageByIndex(m_ImageMouseOverIndex),ref m_LargestImageSize);
if (m_ImageIndex >= 0 && m_LargestImageSize.IsEmpty)
{
if (this.Parent != null && this.Parent.TreeControl != null && this.Parent.TreeControl.ImageList != null)
m_LargestImageSize = this.Parent.TreeControl.ImageList.ImageSize;
}
}
private void AdjustSize(System.Drawing.Image image, ref Size size)
{
if(image!=null)
{
if(image.Width>size.Width)
size.Width=image.Width;
if(image.Height>size.Height)
size.Height=image.Height;
}
}
/// <summary>
/// Returns image from image list based on the image index.
/// </summary>
/// <param name="imageIndex">Index of the image to return.</param>
/// <returns>Image object from image list.</returns>
internal System.Drawing.Image GetImageByIndex(int imageIndex)
{
if(imageIndex>=0 && this.Parent!=null && this.Parent.TreeControl!=null && this.Parent.TreeControl.ImageList!=null)
{
if (this.Parent.TreeControl.ImageList.Images.Count > imageIndex)
return this.Parent.TreeControl.ImageList.Images[imageIndex];
return null;
}
else
return null;
}
#endregion
}
}

View File

@@ -0,0 +1,472 @@
using System;
using System.Drawing;
namespace DevComponents.Tree
{
/// <summary>
/// Represents the class that provides color support to ColorScheme object.
/// </summary>
internal class ColorFunctions
{
#region Private Variables
private static Color m_HoverBackColor;
private static Color m_HoverBackColor2;
private static Color m_HoverBackColor3;
private static Color m_CheckBoxBackColor;
private static Color m_MenuBackColor;
private static Color m_MenuFocusBorderColor;
private static Color m_PressedBackColor;
private static Color m_ToolMenuFocusBackColor;
private static Color m_SideRecentlyBackColor;
private static Color m_RecentlyUsedOfficeBackColor;
private static bool m_ThemedOS=false;
private static Bitmap m_PushedBrushBmp=null;
#endregion
#region Win32 Interop
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct OSVERSIONINFO
{
public int dwOSVersionInfoSize;
public int dwMajorVersion;
public int dwMinorVersion;
public int dwBuildNumber;
public int dwPlatformId;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=128)]
public string szCSDVersion;
}
[System.Runtime.InteropServices.DllImport("kernel32.Dll")] private static extern short GetVersionEx(ref OSVERSIONINFO o);
[System.Runtime.InteropServices.DllImport("gdi32")]
private static extern int CreateDC(string lpszDriver, int lpszDevice, int lpszOutput, int lpInitData);
[System.Runtime.InteropServices.DllImport("gdi32")]
private static extern bool DeleteDC(int hDC);
[System.Runtime.InteropServices.DllImport("gdi32",SetLastError=true, CharSet=System.Runtime.InteropServices.CharSet.Auto)]
private static extern int GetDeviceCaps(int hdc, int nIndex);
private const int BITSPIXEL = 12; // Number of bits per pixel
#endregion
public static void Initialize()
{
OnDisplayChange();
OSVERSIONINFO os = new OSVERSIONINFO();
os.dwOSVersionInfoSize=System.Runtime.InteropServices.Marshal.SizeOf(typeof(OSVERSIONINFO));
GetVersionEx(ref os);
if(os.dwMajorVersion>=5 && os.dwMinorVersion>=1 && os.dwPlatformId==2)
m_ThemedOS=System.Windows.Forms.OSFeature.Feature.IsPresent(System.Windows.Forms.OSFeature.Themes);
RefreshColors();
}
public static void RefreshColors()
{
if(ColorDepth>=16)
{
int red=(int)((System.Drawing.SystemColors.Highlight.R-System.Drawing.SystemColors.Window.R)*.30+System.Drawing.SystemColors.Window.R);
int green=(int)((System.Drawing.SystemColors.Highlight.G-System.Drawing.SystemColors.Window.G)*.30+System.Drawing.SystemColors.Window.G);
int blue=(int)((System.Drawing.SystemColors.Highlight.B-System.Drawing.SystemColors.Window.B)*.30+System.Drawing.SystemColors.Window.B);
m_HoverBackColor=Color.FromArgb(red,green,blue);
red=(int)((System.Drawing.SystemColors.Highlight.R-System.Drawing.SystemColors.Window.R)*.45+System.Drawing.SystemColors.Window.R);
green=(int)((System.Drawing.SystemColors.Highlight.G-System.Drawing.SystemColors.Window.G)*.45+System.Drawing.SystemColors.Window.G);
blue=(int)((System.Drawing.SystemColors.Highlight.B-System.Drawing.SystemColors.Window.B)*.45+System.Drawing.SystemColors.Window.B);
m_HoverBackColor2=Color.FromArgb(red,green,blue);
red=(int)((System.Drawing.SystemColors.Highlight.R-System.Drawing.SystemColors.Window.R)*.10+System.Drawing.SystemColors.Window.R);
green=(int)((System.Drawing.SystemColors.Highlight.G-System.Drawing.SystemColors.Window.G)*.10+System.Drawing.SystemColors.Window.G);
blue=(int)((System.Drawing.SystemColors.Highlight.B-System.Drawing.SystemColors.Window.B)*.10+System.Drawing.SystemColors.Window.B);
m_HoverBackColor3=Color.FromArgb(red,green,blue);
red=(int)((System.Drawing.SystemColors.Highlight.R-System.Drawing.SystemColors.Window.R)*.25+System.Drawing.SystemColors.Window.R);
green=(int)((System.Drawing.SystemColors.Highlight.G-System.Drawing.SystemColors.Window.G)*.25+System.Drawing.SystemColors.Window.G);
blue=(int)((System.Drawing.SystemColors.Highlight.B-System.Drawing.SystemColors.Window.B)*.25+System.Drawing.SystemColors.Window.B);
m_CheckBoxBackColor=Color.FromArgb(red,green,blue);
if(ColorDepth<=16)
{
m_MenuBackColor=System.Drawing.SystemColors.ControlLightLight;
}
else
{
red=(int)((System.Drawing.SystemColors.Control.R-System.Drawing.Color.White.R)*.20+System.Drawing.Color.White.R);
green=(int)((System.Drawing.SystemColors.Control.G-System.Drawing.Color.White.G)*.20+System.Drawing.Color.White.G);
blue=(int)((System.Drawing.SystemColors.Control.B-System.Drawing.Color.White.B)*.20+System.Drawing.Color.White.B);
m_MenuBackColor=Color.FromArgb(red,green,blue);
}
red=(int)(System.Drawing.SystemColors.ControlDark.R*.80);
green=(int)(System.Drawing.SystemColors.ControlDark.G*.80);
blue=(int)(System.Drawing.SystemColors.ControlDark.B*.80);
m_MenuFocusBorderColor=Color.FromArgb(red,green,blue);
// and Highlight color
red=(int)((System.Drawing.SystemColors.Highlight.R-System.Drawing.SystemColors.Window.R)*.25+System.Drawing.SystemColors.Window.R);
green=(int)((System.Drawing.SystemColors.Highlight.G-System.Drawing.SystemColors.Window.G)*.25+System.Drawing.SystemColors.Window.G);
blue=(int)((System.Drawing.SystemColors.Highlight.B-System.Drawing.SystemColors.Window.B)*.25+System.Drawing.SystemColors.Window.B);
m_PressedBackColor=Color.FromArgb(red,green,blue);
red=(int)((System.Drawing.SystemColors.Control.R-System.Drawing.Color.White.R)*.80+System.Drawing.Color.White.R);
green=(int)((System.Drawing.SystemColors.Control.G-System.Drawing.Color.White.G)*.80+System.Drawing.Color.White.G);
blue=(int)((System.Drawing.SystemColors.Control.B-System.Drawing.Color.White.B)*.80+System.Drawing.Color.White.B);
m_ToolMenuFocusBackColor=Color.FromArgb(red,green,blue);
red=(int)((System.Drawing.SystemColors.Control.R-System.Drawing.Color.White.R)*.50+System.Drawing.Color.White.R);
green=(int)((System.Drawing.SystemColors.Control.G-System.Drawing.Color.White.G)*.50+System.Drawing.Color.White.G);
blue=(int)((System.Drawing.SystemColors.Control.B-System.Drawing.Color.White.B)*.50+System.Drawing.Color.White.B);
m_RecentlyUsedOfficeBackColor=Color.FromArgb(red,green,blue);
m_SideRecentlyBackColor=System.Drawing.SystemColors.Control;
}
else
{
m_HoverBackColor=System.Drawing.SystemColors.ControlLightLight;
m_HoverBackColor2=m_HoverBackColor;
m_HoverBackColor3=m_HoverBackColor;
m_CheckBoxBackColor=System.Drawing.SystemColors.ControlLight;
m_MenuBackColor=System.Drawing.SystemColors.ControlLightLight;
m_MenuFocusBorderColor=System.Drawing.SystemColors.ControlDark;
m_PressedBackColor=System.Drawing.SystemColors.ControlLight;
m_ToolMenuFocusBackColor=System.Drawing.SystemColors.ControlLight;
m_RecentlyUsedOfficeBackColor=System.Drawing.SystemColors.ControlLight;
m_SideRecentlyBackColor=System.Drawing.SystemColors.Control;
}
if(m_PushedBrushBmp!=null)
{
m_PushedBrushBmp.Dispose();
m_PushedBrushBmp=new System.Drawing.Bitmap(2,2);
m_PushedBrushBmp.SetPixel(0,0,System.Drawing.SystemColors.Control);
m_PushedBrushBmp.SetPixel(1,0,System.Drawing.SystemColors.ControlLightLight);
m_PushedBrushBmp.SetPixel(0,1,System.Drawing.SystemColors.ControlLightLight);
m_PushedBrushBmp.SetPixel(1,1,System.Drawing.SystemColors.Control);
}
}
public struct HLSColor
{
public double Hue;
public double Lightness;
public double Saturation;
}
public struct RGBColor
{
public int Red;
public int Green;
public int Blue;
}
public static HLSColor RGBToHSL(int Red, int Green, int Blue)
{
double Max, Min, delta;
double rR, rG, rB;
HLSColor ret=new HLSColor();
rR = (double)Red / 255;
rG = (double)Green / 255;
rB = (double)Blue / 255;
// Given: rgb each in [0,1].
// Desired: h in [0,360] and s in [0,1], except if s=0, then h=UNDEFINED.}
Max = Maximum(rR, rG, rB);
Min = Minimum(rR, rG, rB);
ret.Lightness = (Max + Min) / 2; // {This is the lightness}
// {Next calculate saturation}
if(Max == Min)
{
// begin {Acrhomatic case}
ret.Saturation = 0;
ret.Hue = 0;
// end {Acrhomatic case}
}
else
{
// begin {Chromatic case}
// {First calculate the saturation.}
if(ret.Lightness <= 0.5)
ret.Saturation = (Max - Min) / (Max + Min);
else
ret.Saturation = (Max - Min) / (2 - Max - Min);
// {Next calculate the hue.}
delta = Max - Min;
if(rR == Max)
ret.Hue = (rG - rB) / delta; //{Resulting color is between yellow and magenta}
else if(rG == Max)
ret.Hue = 2 + (rB - rR) / delta; // {Resulting color is between cyan and yellow}
else if(rB == Max)
ret.Hue = 4 + (rR - rG) / delta; // {Resulting color is between magenta and cyan}
}
return ret;
}
public static HLSColor RGBToHSL(RGBColor clr)
{
return RGBToHSL(clr.Red,clr.Green,clr.Blue);
}
private static double Maximum(double rR, double rG, double rB)
{
double ret=0;
if(rR > rG)
{
if(rR > rB)
ret = rR;
else
ret = rB;
}
else
{
if(rB > rG)
ret = rB;
else
ret = rG;
}
return ret;
}
private static double Minimum(double rR, double rG, double rB)
{
double ret=0;
if(rR < rG)
{
if(rR < rB)
ret = rR;
else
ret = rB;
}
else
{
if(rB < rG)
ret = rB;
else
ret = rG;
}
return ret;
}
public static RGBColor HLSToRGB(double Hue, double Lightness, double Saturation)
{
double rR, rG, rB;
double Min, Max;
RGBColor ret=new RGBColor();
if(Saturation == 0)
{
// Achromatic case:
rR = Lightness;
rG = Lightness;
rB = Lightness;
}
else
{
// Chromatic case:
// delta = Max-Min
if(Lightness <= 0.5)
{
Min = Lightness * (1 - Saturation);
}
else
{
Min = Lightness - Saturation * (1 - Lightness);
}
// Get the Max value:
Max = 2 * Lightness - Min;
// Now depending on sector we can evaluate the h,l,s:
if(Hue < 1)
{
rR = Max;
if(Hue < 0)
{
rG = Min;
rB = rG - Hue * (Max - Min);
}
else
{
rB = Min;
rG = Hue * (Max - Min) + rB;
}
}
else if (Hue < 3)
{
rG = Max;
if(Hue < 2)
{
rB = Min;
rR = rB - (Hue - 2) * (Max - Min);
}
else
{
rR = Min;
rB = (Hue - 2) * (Max - Min) + rR;
}
}
else
{
rB = Max;
if(Hue < 4)
{
rR = Min;
rG = rR - (Hue - 4) * (Max - Min);
}
else
{
rG = Min;
rR = (Hue - 4) * (Max - Min) + rG;
}
}
}
ret.Red = (int)(rR * 255);
ret.Green = (int)(rG * 255);
ret.Blue = (int)(rB * 255);
if(ret.Red>255)
ret.Red=255;
if(ret.Green>255)
ret.Green=255;
if(ret.Blue>255)
ret.Blue=255;
return ret;
}
public static RGBColor HLSToRGB(HLSColor clr)
{
return HLSToRGB(clr.Hue,clr.Lightness,clr.Saturation);
}
public static System.Drawing.Color HoverBackColor()
{
return m_HoverBackColor;
}
public static System.Drawing.Color HoverBackColor2()
{
return m_HoverBackColor2;
}
public static System.Drawing.Color HoverBackColor3()
{
return m_HoverBackColor3;
}
public static System.Drawing.Color HoverBackColor(System.Drawing.Graphics g)
{
return g.GetNearestColor(HoverBackColor());
}
public static System.Drawing.Color PressedBackColor()
{
return m_PressedBackColor;
}
public static System.Drawing.Color PressedBackColor(System.Drawing.Graphics g)
{
return g.GetNearestColor(PressedBackColor());
}
public static System.Drawing.Color CheckBoxBackColor()
{
return m_CheckBoxBackColor;
}
public static System.Drawing.Color CheckBoxBackColor(System.Drawing.Graphics g)
{
return g.GetNearestColor(CheckBoxBackColor());
}
public static System.Drawing.Color ToolMenuFocusBackColor()
{
return m_ToolMenuFocusBackColor;
}
public static System.Drawing.Color RecentlyUsedOfficeBackColor()
{
return m_RecentlyUsedOfficeBackColor;
}
public static System.Drawing.Color RecentlyUsedOfficeBackColor(System.Drawing.Graphics g)
{
return g.GetNearestColor(RecentlyUsedOfficeBackColor());
}
public static System.Drawing.Color SideRecentlyBackColor(System.Drawing.Graphics g)
{
return g.GetNearestColor(SideRecentlyBackColor());
}
public static System.Drawing.Color SideRecentlyBackColor()
{
return m_SideRecentlyBackColor;
}
public static System.Drawing.Color ToolMenuFocusBackColor(System.Drawing.Graphics g)
{
return g.GetNearestColor(ToolMenuFocusBackColor());
}
public static System.Drawing.Color MenuFocusBorderColor()
{
return m_MenuFocusBorderColor;
}
public static System.Drawing.Color MenuFocusBorderColor(System.Drawing.Graphics g)
{
return g.GetNearestColor(MenuFocusBorderColor());
}
public static System.Drawing.Color MenuBackColor()
{
return m_MenuBackColor;
}
public static System.Drawing.Color MenuBackColor(System.Drawing.Graphics g)
{
return g.GetNearestColor(MenuBackColor());
}
public static System.Drawing.TextureBrush GetPushedBrush()
{
if(m_PushedBrushBmp==null)
{
m_PushedBrushBmp=new System.Drawing.Bitmap(2,2);
m_PushedBrushBmp.SetPixel(0,0,System.Drawing.SystemColors.Control);
m_PushedBrushBmp.SetPixel(1,0,System.Drawing.SystemColors.ControlLightLight);
m_PushedBrushBmp.SetPixel(0,1,System.Drawing.SystemColors.ControlLightLight);
m_PushedBrushBmp.SetPixel(1,1,System.Drawing.SystemColors.Control);
}
return (new System.Drawing.TextureBrush(m_PushedBrushBmp));
}
public static bool ThemedOS
{
get{return m_ThemedOS;}
set{m_ThemedOS=value;}
}
public static eWinXPColorScheme WinXPColorScheme
{
get
{
eWinXPColorScheme c=eWinXPColorScheme.Undetermined;
if(ThemedOS && ColorDepth>=16)
{
if(SystemColors.Control.ToArgb()==Color.FromArgb(236,233,216).ToArgb() && SystemColors.Highlight.ToArgb()==Color.FromArgb(49,106,197).ToArgb())
c=eWinXPColorScheme.Blue;
else if(SystemColors.Control.ToArgb()==Color.FromArgb(224,223,227).ToArgb() && SystemColors.Highlight.ToArgb()==Color.FromArgb(178,180,191).ToArgb())
c=eWinXPColorScheme.Silver;
else if(SystemColors.Control.ToArgb()==Color.FromArgb(236,233,216).ToArgb() && SystemColors.Highlight.ToArgb()==Color.FromArgb(147,160,112).ToArgb())
c=eWinXPColorScheme.OliveGreen;
}
return c;
}
}
public static int ColorDepth=0;
internal static void OnDisplayChange()
{
int hdc = CreateDC("DISPLAY", 0, 0, 0);
ColorDepth = GetDeviceCaps(hdc, BITSPIXEL);
DeleteDC(hdc);
}
}
}

View File

@@ -0,0 +1,658 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
namespace DevComponents.UI
{
/// <summary>
/// Provides popup color picker.
/// </summary>
[ToolboxItem(false)]
internal class ColorPicker : UserControl
{
#region Private Variables
private Color[] m_CustomColors=new Color[48];
private Rectangle[] m_CustomColorsPos=new Rectangle[48];
private object m_ColorScheme=null;
private string m_TransText="";
private TabControl tabControl1;
private TabPage tabPage1;
private TabPage tabPage2;
private TabPage tabPage3;
private TabPage tabPage4;
private Label label1;
private ListBox listScheme;
private Button btnOK;
private Button btnCancel;
private Panel colorPanel;
private ListBox listSystem;
private ListBox listWeb;
private Color m_SelectedColor=Color.Empty;
private string m_SelectedColorSchemeName="";
private Panel colorPreview;
private TrackBar transparencyTrack;
private bool m_Canceled=false;
private System.Windows.Forms.Design.IWindowsFormsEditorService m_EditorService=null;
/// <summary>
/// Required designer variable.
/// </summary>
private Container components = null;
#endregion
#region Constructor and Dispose
public ColorPicker()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
InitCustomColors();
InitOtherColors();
m_TransText=label1.Text;
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#endregion
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.listScheme = new System.Windows.Forms.ListBox();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.listSystem = new System.Windows.Forms.ListBox();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.listWeb = new System.Windows.Forms.ListBox();
this.tabPage4 = new System.Windows.Forms.TabPage();
this.colorPanel = new System.Windows.Forms.Panel();
this.transparencyTrack = new System.Windows.Forms.TrackBar();
this.label1 = new System.Windows.Forms.Label();
this.colorPreview = new System.Windows.Forms.Panel();
this.btnOK = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.tabPage3.SuspendLayout();
this.tabPage4.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.transparencyTrack)).BeginInit();
this.SuspendLayout();
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Controls.Add(this.tabPage4);
this.tabControl1.Location = new System.Drawing.Point(1, 1);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(208, 192);
this.tabControl1.TabIndex = 0;
this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged);
//
// tabPage1
//
this.tabPage1.Controls.Add(this.listScheme);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Size = new System.Drawing.Size(200, 166);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Scheme";
//
// listScheme
//
this.listScheme.Dock = System.Windows.Forms.DockStyle.Fill;
this.listScheme.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.listScheme.IntegralHeight = false;
this.listScheme.Location = new System.Drawing.Point(0, 0);
this.listScheme.Name = "listScheme";
this.listScheme.Size = new System.Drawing.Size(200, 166);
this.listScheme.TabIndex = 0;
this.listScheme.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.DrawColorItem);
this.listScheme.SelectedIndexChanged += new System.EventHandler(this.ListSelectionChange);
//
// tabPage2
//
this.tabPage2.Controls.Add(this.listSystem);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Size = new System.Drawing.Size(200, 166);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "System";
//
// listSystem
//
this.listSystem.Dock = System.Windows.Forms.DockStyle.Fill;
this.listSystem.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.listSystem.IntegralHeight = false;
this.listSystem.Location = new System.Drawing.Point(0, 0);
this.listSystem.Name = "listSystem";
this.listSystem.Size = new System.Drawing.Size(200, 166);
this.listSystem.TabIndex = 1;
this.listSystem.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.DrawColorItem);
this.listSystem.SelectedIndexChanged += new System.EventHandler(this.ListSelectionChange);
//
// tabPage3
//
this.tabPage3.Controls.Add(this.listWeb);
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(200, 166);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Web";
//
// listWeb
//
this.listWeb.Dock = System.Windows.Forms.DockStyle.Fill;
this.listWeb.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.listWeb.IntegralHeight = false;
this.listWeb.Location = new System.Drawing.Point(0, 0);
this.listWeb.Name = "listWeb";
this.listWeb.Size = new System.Drawing.Size(200, 166);
this.listWeb.TabIndex = 1;
this.listWeb.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.DrawColorItem);
this.listWeb.SelectedIndexChanged += new System.EventHandler(this.ListSelectionChange);
//
// tabPage4
//
this.tabPage4.Controls.Add(this.colorPanel);
this.tabPage4.Location = new System.Drawing.Point(4, 22);
this.tabPage4.Name = "tabPage4";
this.tabPage4.Size = new System.Drawing.Size(200, 166);
this.tabPage4.TabIndex = 3;
this.tabPage4.Text = "Custom";
//
// colorPanel
//
this.colorPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.colorPanel.Location = new System.Drawing.Point(0, 0);
this.colorPanel.Name = "colorPanel";
this.colorPanel.Size = new System.Drawing.Size(200, 166);
this.colorPanel.TabIndex = 0;
this.colorPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.CustomColorMouseUp);
this.colorPanel.Paint += new System.Windows.Forms.PaintEventHandler(this.PaintCustomColors);
//
// transparencyTrack
//
this.transparencyTrack.Enabled = false;
this.transparencyTrack.Location = new System.Drawing.Point(1, 204);
this.transparencyTrack.Maximum = 255;
this.transparencyTrack.Name = "transparencyTrack";
this.transparencyTrack.Size = new System.Drawing.Size(200, 45);
this.transparencyTrack.TabIndex = 1;
this.transparencyTrack.TickFrequency = 16;
this.transparencyTrack.Value = 255;
this.transparencyTrack.ValueChanged += new System.EventHandler(this.transparencyTrack_ValueChanged);
//
// label1
//
this.label1.Location = new System.Drawing.Point(1, 194);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(136, 16);
this.label1.TabIndex = 2;
this.label1.Text = "Transparency";
//
// colorPreview
//
this.colorPreview.BackColor = System.Drawing.Color.White;
this.colorPreview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.colorPreview.Location = new System.Drawing.Point(8, 240);
this.colorPreview.Name = "colorPreview";
this.colorPreview.Size = new System.Drawing.Size(40, 32);
this.colorPreview.TabIndex = 3;
this.colorPreview.Paint += new System.Windows.Forms.PaintEventHandler(this.colorPreview_Paint);
//
// btnOK
//
this.btnOK.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnOK.Location = new System.Drawing.Point(72, 248);
this.btnOK.Name = "btnOK";
this.btnOK.Size = new System.Drawing.Size(64, 24);
this.btnOK.TabIndex = 4;
this.btnOK.Text = "OK";
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// btnCancel
//
this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.btnCancel.Location = new System.Drawing.Point(142, 248);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(64, 24);
this.btnCancel.TabIndex = 5;
this.btnCancel.Text = "Cancel";
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// ColorPicker
//
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOK);
this.Controls.Add(this.colorPreview);
this.Controls.Add(this.label1);
this.Controls.Add(this.tabControl1);
this.Controls.Add(this.transparencyTrack);
this.DockPadding.All = 1;
this.Name = "ColorPicker";
this.Size = new System.Drawing.Size(211, 280);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.ColorPicker_Paint);
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
this.tabPage3.ResumeLayout(false);
this.tabPage4.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.transparencyTrack)).EndInit();
this.ResumeLayout(false);
}
#endregion
#region Color Init
private void InitCustomColors()
{
m_CustomColors[0]=Color.FromArgb(255,255,255);
m_CustomColors[1]=Color.FromArgb(255,195,198);
m_CustomColors[2]=Color.FromArgb(255,227,198);
m_CustomColors[3]=Color.FromArgb(255,255,198);
m_CustomColors[4]=Color.FromArgb(198,255,198);
m_CustomColors[5]=Color.FromArgb(198,255,255);
m_CustomColors[6]=Color.FromArgb(198,195,255);
m_CustomColors[7]=Color.FromArgb(255,195,255);
m_CustomColors[8]=Color.FromArgb(231,227,231);
m_CustomColors[9]=Color.FromArgb(255,130,132);
m_CustomColors[10]=Color.FromArgb(255,195,132);
m_CustomColors[11]=Color.FromArgb(255,255,132);
m_CustomColors[12]=Color.FromArgb(132,255,132);
m_CustomColors[13]=Color.FromArgb(132,255,255);
m_CustomColors[14]=Color.FromArgb(132,130,255);
m_CustomColors[15]=Color.FromArgb(255,130,255);
m_CustomColors[16]=Color.FromArgb(198,195,198);
m_CustomColors[17]=Color.FromArgb(255,0,0);
m_CustomColors[18]=Color.FromArgb(255,130,0);
m_CustomColors[19]=Color.FromArgb(255,255,0);
m_CustomColors[20]=Color.FromArgb(0,255,0);
m_CustomColors[21]=Color.FromArgb(0,255,255);
m_CustomColors[22]=Color.FromArgb(0,0,255);
m_CustomColors[23]=Color.FromArgb(255,0,255);
m_CustomColors[24]=Color.FromArgb(132,130,132);
m_CustomColors[25]=Color.FromArgb(198,0,0);
m_CustomColors[26]=Color.FromArgb(198,65,0);
m_CustomColors[27]=Color.FromArgb(198,195,0);
m_CustomColors[28]=Color.FromArgb(0,195,0);
m_CustomColors[29]=Color.FromArgb(0,195,198);
m_CustomColors[30]=Color.FromArgb(0,0,198);
m_CustomColors[31]=Color.FromArgb(198,0,198);
m_CustomColors[32]=Color.FromArgb(66,65,66);
m_CustomColors[33]=Color.FromArgb(132,0,0);
m_CustomColors[34]=Color.FromArgb(132,65,0);
m_CustomColors[35]=Color.FromArgb(132,130,0);
m_CustomColors[36]=Color.FromArgb(0,130,0);
m_CustomColors[37]=Color.FromArgb(0,130,132);
m_CustomColors[38]=Color.FromArgb(0,0,132);
m_CustomColors[39]=Color.FromArgb(132,0,132);
m_CustomColors[40]=Color.FromArgb(0,0,0);
m_CustomColors[41]=Color.FromArgb(66,0,0);
m_CustomColors[42]=Color.FromArgb(132,65,66);
m_CustomColors[43]=Color.FromArgb(66,65,0);
m_CustomColors[44]=Color.FromArgb(0,65,0);
m_CustomColors[45]=Color.FromArgb(0,65,66);
m_CustomColors[46]=Color.FromArgb(0,0,66);
m_CustomColors[47]=Color.FromArgb(66,0,66);
}
private void InitOtherColors()
{
listWeb.BeginUpdate();
listWeb.Items.Clear();
Type type = typeof(Color);
PropertyInfo[] fields=type.GetProperties(BindingFlags.Public | BindingFlags.Static);
Color clr=new Color();
foreach(PropertyInfo pi in fields)
listWeb.Items.Add(pi.GetValue(clr,null));
listWeb.EndUpdate();
listSystem.BeginUpdate();
listSystem.Items.Clear();
type=typeof(SystemColors);
fields=type.GetProperties(BindingFlags.Public | BindingFlags.Static);
foreach(PropertyInfo pi in fields)
listSystem.Items.Add(pi.GetValue(clr,null));
listSystem.EndUpdate();
}
private void InitColorSchemeColors()
{
if(m_ColorScheme!=null)
{
if(!tabControl1.TabPages.Contains(tabPage1))
{
tabControl1.TabPages.Add(tabPage1);
}
listScheme.BeginUpdate();
listScheme.Items.Clear();
Type type=m_ColorScheme.GetType();
PropertyInfo[] fields=type.GetProperties();
foreach(PropertyInfo pi in fields)
{
if(pi.PropertyType==typeof(Color))
listScheme.Items.Add(pi.Name);
}
listScheme.EndUpdate();
}
else
{
if(tabControl1.TabPages.Contains(tabPage1))
tabControl1.TabPages.Remove(tabPage1);
}
}
#endregion
#region Public Interface
/// <summary>
/// Gets or sets the windows forms editor service. This property must be set if color picker is used with UITypeEditorEditStyle.DropDown style.
/// </summary>
public System.Windows.Forms.Design.IWindowsFormsEditorService EditorService
{
get {return m_EditorService;}
set {m_EditorService=value;}
}
/// <summary>
/// Gets or sets the ColorScheme object for Scheme colors.
/// </summary>
[Browsable(false),DefaultValue(null)]
public object ColorScheme
{
get {return m_ColorScheme;}
set
{
m_ColorScheme=value;
InitColorSchemeColors();
}
}
/// <summary>
/// Gets or sets currently selected color.
/// </summary>
public Color SelectedColor
{
get {return m_SelectedColor;}
set
{
m_SelectedColor=value;
OnSelectedColorChanged();
}
}
/// <summary>
/// Gets the selected color color scheme name if color scheme color is selected otherwise it returns an empty string.
/// </summary>
public string SelectedColorSchemeName
{
get {return m_SelectedColorSchemeName;}
set
{
m_SelectedColorSchemeName=value;
}
}
/// <summary>
/// Returns true if color selection was cancelled.
/// </summary>
public bool Canceled
{
get {return m_Canceled;}
}
#endregion
#region Painting
private void PaintCustomColors(object sender, PaintEventArgs e)
{
Rectangle r=Rectangle.Empty;
int x=6, y=12;
Graphics g=e.Graphics;
Border3DSide side=(Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
int width=colorPanel.ClientRectangle.Width;
int iIndex=0;
foreach(Color clr in m_CustomColors)
{
r=new Rectangle(x,y,21,21);
if(r.Right>width)
{
y+=25;
x=6;
r.X=x;
r.Y=y;
}
ControlPaint.DrawBorder3D(g,x,y,21,21,Border3DStyle.Sunken,side);
r.Inflate(-2,-2);
g.FillRectangle(new SolidBrush(clr),r);
m_CustomColorsPos[iIndex]=r;
iIndex++;
x+=24;
}
}
private void DrawColorItem(object sender, DrawItemEventArgs e)
{
Rectangle r=e.Bounds;
Rectangle rClr=new Rectangle(r.X+1,r.Y+2,24,r.Height-4);
ListBox list=sender as ListBox;
Brush textbrush=SystemBrushes.ControlText;
if((e.State & DrawItemState.Selected)!=0)
{
textbrush=SystemBrushes.HighlightText;
e.Graphics.FillRectangle(SystemBrushes.Highlight,e.Bounds);
}
else
e.Graphics.FillRectangle(SystemBrushes.Window,e.Bounds);
Color clr=Color.Empty;
string colorName="";
if(list.Items[e.Index].GetType()==typeof(Color))
{
clr=(Color)list.Items[e.Index];
colorName=clr.Name;
}
else
{
colorName=list.Items[e.Index].ToString();
clr=(Color)m_ColorScheme.GetType().GetProperty(colorName).GetValue(m_ColorScheme,null);
}
e.Graphics.FillRectangle(new SolidBrush(clr),rClr);
e.Graphics.DrawRectangle(SystemPens.ControlText,rClr);
r.Offset(30,0);
r.Width-=30;
e.Graphics.DrawString(colorName,list.Font,textbrush,r,StringFormat.GenericTypographic);
}
#endregion
#region Internals
private void CustomColorMouseUp(object sender, MouseEventArgs e)
{
for(int i=0;i<48;i++)
{
if(m_CustomColorsPos[i].Contains(e.X,e.Y))
{
this.SelectedColor=m_CustomColors[i];
m_SelectedColorSchemeName="";
break;
}
}
}
private void ListSelectionChange(object sender, EventArgs e)
{
ListBox list=sender as ListBox;
if(list.SelectedItem!=null)
{
if(list.SelectedItem is Color)
{
this.SelectedColor=(Color)list.SelectedItem;
m_SelectedColorSchemeName="";
}
else
{
m_SelectedColorSchemeName=list.SelectedItem.ToString();
this.SelectedColor=(Color)m_ColorScheme.GetType().GetProperty(this.SelectedColorSchemeName).GetValue(m_ColorScheme,null);
}
}
else
{
this.SelectedColor=Color.Empty;
m_SelectedColorSchemeName="";
}
}
private void OnSelectedColorChanged()
{
colorPreview.BackColor=m_SelectedColor;
transparencyTrack.Value=m_SelectedColor.A;
UpdateTransparencyText();
}
public void UpdateUIWithSelection()
{
listSystem.SelectedIndex = -1;
listWeb.SelectedIndex = -1;
listScheme.SelectedIndex = -1;
if(m_SelectedColor.IsSystemColor)
{
tabControl1.SelectedTab = tabPage2;
SelectListBoxItem(listSystem,m_SelectedColor.Name);
}
else if(m_SelectedColor.IsNamedColor)
{
tabControl1.SelectedTab = tabPage3;
SelectListBoxItem(listWeb,m_SelectedColor.Name);
}
else if(m_SelectedColorSchemeName!="")
{
tabControl1.SelectedTab = tabPage1;
SelectListBoxItem(listScheme,m_SelectedColorSchemeName);
}
else
{
tabControl1.SelectedTab = tabPage4;
}
}
private void SelectListBoxItem(ListBox listBox, string item)
{
foreach(object o in listBox.Items)
{
if(o.ToString()==item)
{
listBox.SelectedItem = o;
return;
}
}
}
private void UpdateTransparencyText()
{
if(!this.SelectedColor.IsEmpty)
{
label1.Text=m_TransText + " (" + this.SelectedColor.A.ToString()+")";
}
else
label1.Text=m_TransText;
}
private void transparencyTrack_ValueChanged(object sender, EventArgs e)
{
if(!this.SelectedColor.IsEmpty && this.SelectedColor.A!=transparencyTrack.Value)
{
this.SelectedColor=Color.FromArgb(transparencyTrack.Value,this.SelectedColor);
m_SelectedColorSchemeName="";
}
UpdateTransparencyText();
}
private void colorPreview_Paint(object sender, PaintEventArgs e)
{
if(this.SelectedColor.IsEmpty)
{
Rectangle r=this.colorPreview.ClientRectangle;
r.Inflate(-2,-2);
e.Graphics.DrawLine(SystemPens.ControlText,r.X,r.Y,r.Right,r.Bottom);
e.Graphics.DrawLine(SystemPens.ControlText,r.Right,r.Y,r.X,r.Bottom);
}
}
private void btnOK_Click(object sender, EventArgs e)
{
this.ClosePicker();
}
private void btnCancel_Click(object sender, EventArgs e)
{
m_Canceled=true;
this.ClosePicker();
}
private void ClosePicker()
{
if(m_EditorService!=null)
{
m_EditorService.CloseDropDown();
return;
}
if(this.Parent!=null)
this.Parent.Hide();
else
this.Hide();
}
private void ColorPicker_Paint(object sender, PaintEventArgs e)
{
Rectangle r=this.ClientRectangle;
r.Width--;
r.Height--;
e.Graphics.DrawRectangle(SystemPens.ControlDarkDark,r);
}
private void tabControl1_SelectedIndexChanged(object sender, System.EventArgs e)
{
if(tabControl1.SelectedIndex==0 && m_ColorScheme!=null)
{
transparencyTrack.Enabled=false;
}
else
transparencyTrack.Enabled=true;
}
#endregion
}
}

View File

@@ -0,0 +1,319 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used forserialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="tabControl1.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="tabControl1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabControl1.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabControl1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabControl1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabControl1.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="tabPage1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabPage1.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="tabPage1.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabPage1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabPage1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabPage1.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="listScheme.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="listScheme.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="listScheme.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabPage2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabPage2.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="tabPage2.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabPage2.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabPage2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabPage2.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="listSystem.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="listSystem.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="listSystem.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabPage3.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabPage3.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="tabPage3.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabPage3.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabPage3.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabPage3.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="listWeb.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="listWeb.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="listWeb.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabPage4.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabPage4.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="tabPage4.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="tabPage4.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabPage4.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="tabPage4.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="colorPanel.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="colorPanel.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="colorPanel.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="colorPanel.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="colorPanel.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="colorPanel.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="transparencyTrack.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="transparencyTrack.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="transparencyTrack.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="label1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="colorPreview.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="colorPreview.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="colorPreview.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="colorPreview.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="colorPreview.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="colorPreview.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="btnOK.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="btnOK.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="btnOK.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="btnCancel.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="btnCancel.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="btnCancel.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>80</value>
</data>
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>(Default)</value>
</data>
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="$this.Name">
<value>ColorPicker</value>
</data>
</root>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,99 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Reflection;
using System.Windows.Forms.Design;
using DevComponents.UI;
#if TREEGX
namespace DevComponents.Tree
#elif DOTNETBAR
namespace DevComponents.DotNetBar
#endif
{
/// <summary>
/// Represents Color type editor with support for color schemes.
/// </summary>
public class ColorTypeEditor:UITypeEditor
{
private IWindowsFormsEditorService m_EditorService=null;
/// <summary>
/// Edits the value of the specified object using the editor style indicated by GetEditStyle.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param>
/// <param name="provider">An IServiceProvider that this editor can use to obtain services.</param>
/// <param name="value">The object to edit.</param>
/// <returns>The new value of the object.</returns>
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context != null && context.Instance != null && provider != null)
{
m_EditorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
ColorScheme cs=null;
if(context.Instance!=null)
{
MethodInfo method=context.Instance.GetType().GetMethod("GetColorScheme",BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if(method!=null)
{
cs=method.Invoke(context.Instance,null) as ColorScheme;
}
}
Color colorValue=(Color)value;
if(m_EditorService!=null)
{
ColorPicker colorPicker=new ColorPicker();
colorPicker.EditorService=m_EditorService;
colorPicker.BackColor=SystemColors.Control;
colorPicker.ColorScheme=cs;
colorPicker.SelectedColor=colorValue;
string propertyName=context.PropertyDescriptor.Name;
PropertyInfo property=context.Instance.GetType().GetProperty(propertyName+"SchemePart",BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if(property!=null)
{
colorPicker.SelectedColorSchemeName=property.GetValue(context.Instance,null).ToString();
}
colorPicker.UpdateUIWithSelection();
m_EditorService.DropDownControl(colorPicker);
if(!colorPicker.Canceled)
{
Color returnColor=colorPicker.SelectedColor;
eColorSchemePart schemePart=eColorSchemePart.None;
if(colorPicker.SelectedColorSchemeName!="")
{
schemePart=(eColorSchemePart)Enum.Parse(typeof(eColorSchemePart),colorPicker.SelectedColorSchemeName);
}
if(property!=null)
{
property.SetValue(context.Instance,schemePart,null);
}
return returnColor;
}
}
}
return value;
}
/// <summary>
/// Gets the editor style used by the EditValue method.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param>
/// <returns>A UITypeEditorEditStyle value that indicates the style of editor used by EditValue. If the UITypeEditor does not support this method, then GetEditStyle will return None.
/// </returns>
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
if (context != null && context.Instance != null)
{
return UITypeEditorEditStyle.DropDown;
}
return base.GetEditStyle(context);
}
}
}

View File

@@ -0,0 +1,268 @@
using System;
using System.ComponentModel;
using System.Drawing;
namespace DevComponents.Tree
{
/// <summary>Represents the node or tree ColumnHeader.</summary>
[ToolboxItem(false)]
public class ColumnHeader:Component
{
#region Private Variables
private string m_Text="";
private ColumnWidth m_Width=null;
private string m_StyleNormal="";
private string m_StyleMouseDown="";
private string m_StyleMouseOver="";
private string m_ColumnName="";
private bool m_Visible=true;
private Rectangle m_Bounds=Rectangle.Empty;
private bool m_SizeChanged=true;
private string m_Name="";
internal event EventHandler HeaderSizeChanged;
#endregion
#region Constructor
/// <summary>
/// Creates new instance of the object.
/// </summary>
public ColumnHeader():this("")
{
}
/// <summary>
/// Creates new instance of the object and initalizes it with text.
/// </summary>
/// <param name="text">Text to initalize object with.</param>
public ColumnHeader(string text)
{
m_Text=text;
m_Width=new ColumnWidth();
m_Width.WidthChanged+=new EventHandler(this.WidthChanged);
}
#endregion
#region Methods
/// <summary>
/// Makes a copy of ColumnHeader object.
/// </summary>
/// <returns>Returns new instance of column header object.</returns>
public virtual ColumnHeader Copy()
{
ColumnHeader c=new ColumnHeader();
c.ColumnName=this.ColumnName;
c.StyleMouseDown=this.StyleMouseDown;
c.StyleMouseOver=this.StyleMouseOver;
c.StyleNormal=this.StyleNormal;
c.Text=this.Text;
c.Visible=this.Visible;
c.Width.Absolute=this.Width.Absolute;
c.Width.Relative=this.Width.Relative;
return c;
}
#endregion
#region Properties
/// <summary>
/// Returns name of the column header that can be used to identify it from the code.
/// </summary>
[Browsable(false),Category("Design"),Description("Indicates the name used to identify column header.")]
public string Name
{
get
{
if(this.Site!=null)
m_Name=this.Site.Name;
return m_Name;
}
set
{
if(this.Site!=null)
this.Site.Name=value;
if(value==null)
m_Name="";
else
m_Name=value;
}
}
/// <summary>
/// Returns rectangle that this column occupies. If the layout has not been performed on the column the return value will be Rectangle.Empty.
/// </summary>
[Browsable(false)]
public Rectangle Bounds
{
get {return m_Bounds;}
}
/// <summary>
/// Sets the column bounds.
/// </summary>
internal void SetBounds(Rectangle bounds)
{
m_Bounds=bounds;
}
/// <summary>
/// Gets the reference to the object that represents width of the column as either
/// absolute or relative value.
/// </summary>
/// <remarks>
/// Set Width using Absolute or Relative properties of ColumnWidth object.
/// </remarks>
/// <seealso cref="ColumnWidth.Absolute">Absolute Property (DevComponents.Tree.ColumnWidth)</seealso>
/// <seealso cref="ColumnWidth.Relative">Relative Property (DevComponents.Tree.ColumnWidth)</seealso>
[Browsable(true),Category("Layout"),Description("Gets or sets the width of the column."),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ColumnWidth Width
{
// TODO: Add Proper TypeConverter for ColumnWidth object and test design-time support
get {return m_Width;}
}
/// <summary>
/// Gets or sets the style class assigned to the column. Empty value indicates that
/// default style is used as specified on cell's parent's control.
/// </summary>
/// <value>
/// Name of the style assigned to the cell or an empty string indicating that default
/// style setting from tree control is applied. Default is empty string.
/// </value>
/// <remarks>
/// When property is set to an empty string the style setting from parent tree
/// controls is used. ColumnStyleNormal on TreeGX control is a root style for a cell.
/// </remarks>
/// <seealso cref="StyleMouseDown">StyleMouseDown Property</seealso>
/// <seealso cref="StyleMouseOver">StyleMouseOver Property</seealso>
[Browsable(true),DefaultValue(""),Category("Style"),Description("Indicates the style class assigned to the column.")]
public string StyleNormal
{
get {return m_StyleNormal;}
set
{
m_StyleNormal=value;
this.OnSizeChanged();
}
}
/// <summary>
/// Gets or sets the style class assigned to the column which is applied when mouse
/// button is pressed over the header. Empty value indicates that default
/// style is used as specified on column's parent.
/// </summary>
/// <value>
/// Name of the style assigned to the column or an empty string indicating that default
/// style setting from tree control is applied. Default is empty string.
/// </value>
/// <remarks>
/// When property is set to an empty string the style setting from parent tree
/// controls is used. ColumnStyleMouseDown on TreeGX control is a root style for a
/// cell.
/// </remarks>
/// <seealso cref="StyleNormal">StyleNormal Property</seealso>
/// <seealso cref="StyleMouseOver">StyleMouseOver Property</seealso>
[Browsable(true),DefaultValue(""),Category("Style"),Description("Indicates the style class assigned to the column when mouse is down.")]
public string StyleMouseDown
{
get {return m_StyleMouseDown;}
set
{
m_StyleMouseDown=value;
this.OnSizeChanged();
}
}
/// <summary>
/// Gets or sets the style class assigned to the column which is applied when mouse is
/// over the column. Empty value indicates that default style is used as specified on column's
/// parent control.
/// </summary>
/// <value>
/// Name of the style assigned to the column or an empty string indicating that default
/// style setting from tree control is applied. Default is empty string.
/// </value>
/// <remarks>
/// When property is set to an empty string the style setting from parent tree
/// controls is used. ColumnStyleMouseOver on TreeGX control is a root style for a
/// cell.
/// </remarks>
/// <seealso cref="StyleNormal">StyleNormal Property</seealso>
/// <seealso cref="StyleMouseDown">StyleMouseDown Property</seealso>
[Browsable(true),DefaultValue(""),Category("Style"),Description("Indicates the style class assigned to the cell when mouse is over the column.")]
public string StyleMouseOver
{
get {return m_StyleMouseOver;}
set
{
m_StyleMouseOver=value;
this.OnSizeChanged();
}
}
/// <summary>
/// Gets or sets the name of the column in the ColumnHeaderCollection.
/// </summary>
[Browsable(true),DefaultValue(""),Category("Data"),Description("Indicates the name of the column in the ColumnHeaderCollection.")]
public string ColumnName
{
get {return m_ColumnName;}
set
{
m_ColumnName=value;
}
}
/// <summary>
/// Gets or sets the column caption.
/// </summary>
[Browsable(true),DefaultValue(""),Category("Appearance"),Description("Indicates column caption.")]
public string Text
{
get {return m_Text;}
set
{
m_Text=value;
}
}
/// <summary>
/// Gets or sets whether column is visible. Hidding the header column will also hide coresponding data column.
/// </summary>
[Browsable(true),DefaultValue(true),Category("Behavior"),Description("Indicates whether column is visible.")]
public bool Visible
{
get {return m_Visible;}
set
{
if(m_Visible!=value)
{
m_Visible=value;
}
}
}
#endregion
#region Internal Implementation
/// <summary>
/// Gets or sets whether column size has changed and it's layout needs to be recalculated.
/// </summary>
internal bool SizeChanged
{
get {return m_SizeChanged;}
set {m_SizeChanged=value;}
}
private void OnSizeChanged()
{
m_SizeChanged=true;
if(HeaderSizeChanged!=null)
HeaderSizeChanged(this,new EventArgs());
}
private void WidthChanged(object sender, EventArgs e)
{
this.OnSizeChanged();
}
#endregion
}
}

View File

@@ -0,0 +1,163 @@
using System;
using System.Collections;
using System.ComponentModel;
namespace DevComponents.Tree
{
/// <summary>
/// Represents collection for ColumnHeader objects.
/// </summary>
public class ColumnHeaderCollection:CollectionBase
{
#region Private Variables
private Node m_ParentNode=null;
#endregion
#region Internal Implementation
/// <summary>
/// Default constructor.
/// </summary>
public ColumnHeaderCollection()
{
}
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Node ParentNode
{
get {return m_ParentNode;}
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">ColumnHeader that is parent of this collection.</param>
internal void SetParentNode(Node parent)
{
m_ParentNode=parent;
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="ch">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(ColumnHeader ch)
{
return List.Add(ch);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public ColumnHeader this[int index]
{
get {return (ColumnHeader)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, ColumnHeader value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(ColumnHeader value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(ColumnHeader value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(ColumnHeader value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(ColumnHeader[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the ColumnHeader array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(ColumnHeader[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
base.OnClear();
}
#endregion
}
#region ColumnHeaderCollectionEditor
/// <summary>
/// Support for ColumnHeader tabs design-time editor.
/// </summary>
public class ColumnHeaderCollectionEditor:System.ComponentModel.Design.CollectionEditor
{
/// <summary>Creates new instance of the class</summary>
/// <param name="type">Type to initialize editor with.</param>
public ColumnHeaderCollectionEditor(Type type):base(type)
{
}
protected override Type CreateCollectionItemType()
{
return typeof(ColumnHeader);
}
protected override Type[] CreateNewItemTypes()
{
return new Type[] {typeof(ColumnHeader)};
}
protected override object CreateInstance(Type itemType)
{
object item=base.CreateInstance(itemType);
if(item is ColumnHeader)
{
ColumnHeader ch=item as ColumnHeader;
ch.Text=ch.Name;
}
return item;
}
}
#endregion
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Drawing;
namespace DevComponents.Tree
{
/// <summary>
/// Class that is used to layout column header.
/// </summary>
internal class ColumnHeaderLayout
{
public ColumnHeaderLayout()
{
}
// 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 static int LayoutColumnHeader(NodeLayoutContextInfo layoutInfo,int x, int y, int clientWidth, int cellHorizontalSpacing)
{
Node node=layoutInfo.ContextNode;
int height=0;
foreach(ColumnHeader col in node.NodesColumns)
{
if(!col.Visible)
continue;
if(col.SizeChanged)
{
// Column for child nodes is always placed below the current node and
// is not included in the node's rectangle
Rectangle bounds=Rectangle.Empty;
bounds.X=x;
bounds.Y=y;
if(col.Width.Relative>0)
bounds.Width=(clientWidth*col.Width.Relative)/100-1;
else
bounds.Width=col.Width.Absolute;
if(col.StyleNormal=="" && col.StyleMouseDown=="" && col.StyleMouseOver=="")
{
bounds.Height=layoutInfo.DefaultHeaderSize.Height;
}
else
{
Size sz=Size.Empty;
if(col.StyleNormal!="")
{
ElementStyleLayout.CalculateStyleSize(layoutInfo.Styles[col.StyleNormal],layoutInfo.DefaultFont);
sz=layoutInfo.Styles[col.StyleNormal].Size;
}
if(sz.Height==0)
bounds.Height=layoutInfo.DefaultHeaderSize.Height;
else
bounds.Height=sz.Height;
}
col.SetBounds(bounds);
col.SizeChanged=false;
x+=(bounds.Width+cellHorizontalSpacing);
if(bounds.Height>height)
height=bounds.Height;
}
else if(col.Bounds.Height>height)
height=col.Bounds.Height;
}
return height;
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
using System.ComponentModel;
namespace DevComponents.Tree
{
/// <summary>
/// Represents the width of the Column. Supports absolute width in Pixels and
/// relative width as percentage of the width of parent control.
/// </summary>
public class ColumnWidth
{
private int m_Relative=0;
private int m_Absolute=0;
internal event EventHandler WidthChanged;
/// <summary>
/// Creates new instance of the object.
/// </summary>
public ColumnWidth()
{
}
/// <summary>
/// Gets or sets relative width expressed as percentage between 1-100. 0 indicates that
/// absolute width will be used.
/// </summary>
/// <remarks>
/// Relative width is expressed as percentage between 1-100 of the parent controls
/// width. 0 indicates that absolute width will be used. Absolute width always takes
/// priority over relative width. For example value of 30 assigned to this property
/// indicates that width of the column will be 30% of the total client width of the
/// control.
/// </remarks>
[DefaultValue(0),Browsable(true),Description("Gets or sets relative width in percent. Valid values are between 1-100 with 0 indicating that absolute width will be used.")]
public int Relative
{
get {return m_Relative;}
set
{
if(m_Relative!=value)
{
m_Relative=value;
OnSizeChanged();
}
}
}
/// <summary>Gets or sets the absolute width of the column in pixels.</summary>
/// <remarks>
/// Absolute width always takes precedence over the relative width of the
/// column.
/// </remarks>
[DefaultValue(0),Browsable(true),Description("Gets or sets the absolute width of the column in pixels.")]
public int Absolute
{
get {return m_Absolute;}
set
{
if(m_Absolute<0)
return;
if(m_Absolute!=value)
{
m_Absolute=value;
if(m_Absolute!=0)
m_Relative=0;
OnSizeChanged();
}
}
}
private void OnSizeChanged()
{
if(WidthChanged!=null)
WidthChanged(this,new EventArgs());
}
}
}

View File

@@ -0,0 +1,30 @@
using System;
namespace DevComponents.Tree
{
/// <summary>
/// Provides event arguments for command button events.
/// </summary>
public class CommandButtonEventArgs:EventArgs
{
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="action">Action type.</param>
/// <param name="node">Context node.</param>
public CommandButtonEventArgs(eTreeAction action, Node node)
{
this.Action=action;
this.Node=node;
}
/// <summary>
/// Indicates the action type that caused the event.
/// </summary>
public eTreeAction Action=eTreeAction.Code;
/// <summary>
/// Indicates the node action is peformed on.
/// </summary>
public DevComponents.Tree.Node Node=null;
}
}

View File

@@ -0,0 +1,154 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
namespace DevComponents.Tree
{
/// <summary>
/// Represents collection of connector points for a node.
/// </summary>
public class ConnectorPointsCollection:CollectionBase
{
#region Private Variables
private Node m_ParentNode=null;
#endregion
#region Internal Implementation
/// <summary>
/// Default constructor.
/// </summary>
public ConnectorPointsCollection()
{
}
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Node ParentNode
{
get {return m_ParentNode;}
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">Node that is parent of this collection.</param>
internal void SetParentNode(Node parent)
{
m_ParentNode=parent;
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="p">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(Point p)
{
return List.Add(p);
}
/// <summary>
/// Adds range of objects to the array.
/// </summary>
/// <param name="ap">Array to add.</param>
public void AddRange(Point[] ap)
{
foreach(Point p in ap)
this.Add(p);
}
/// <summary>
/// Copies objects of the collection to the array.
/// </summary>
/// <returns></returns>
public Point[] ToArray()
{
Point[] ap=new Point[this.Count];
this.CopyTo(ap);
return ap;
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public Point this[int index]
{
get {return (Point)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, Point value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(Point value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(Point value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(Point value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(Point[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the ColumnHeader array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(Point[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
base.OnClear();
}
#endregion
}
}

View File

@@ -0,0 +1,44 @@
using System.Collections;
using System.Drawing;
#if TREEGX
namespace DevComponents.Tree.TextMarkup
#elif DOTNETBAR
namespace DevComponents.UI.ContentManager
#elif SUPERGRID
namespace DevComponents.SuperGrid.TextMarkup
#endif
{
/// <summary>
/// Represents block layout manager responsible for sizing the content blocks.
/// </summary>
public abstract class BlockLayoutManager
{
private Graphics m_Graphics;
/// <summary>
/// Resizes the content block and sets it's Bounds property to reflect new size.
/// </summary>
/// <param name="block">Content block to resize.</param>
/// <param name="availableSize">Content size available for the block in the given line.</param>
public abstract void Layout(IBlock block, Size availableSize);
/// <summary>
/// Performs layout finalization
/// </summary>
/// <param name="containerBounds"></param>
/// <param name="blocksBounds"></param>
/// <param name="lines"></param>
/// <returns></returns>
public abstract Rectangle FinalizeLayout(Rectangle containerBounds, Rectangle blocksBounds, ArrayList lines);
/// <summary>
/// Gets or sets the graphics object used by layout manager.
/// </summary>
public System.Drawing.Graphics Graphics
{
get {return m_Graphics;}
set {m_Graphics=value;}
}
}
}

View File

@@ -0,0 +1,62 @@
using System;
#if TREEGX
namespace DevComponents.Tree.TextMarkup
#elif DOTNETBAR
namespace DevComponents.UI.ContentManager
#endif
{
/// <summary>
/// Specifies orientation of content.
/// </summary>
public enum eContentOrientation
{
/// <summary>
/// Indicates Horizontal orientation of the content.
/// </summary>
Horizontal,
/// <summary>
/// Indicates Vertical orientation of the content.
/// </summary>
Vertical
}
/// <summary>
/// Specifies content horizontal alignment.
/// </summary>
public enum eContentAlignment
{
/// <summary>
/// Content is left aligned.UI
/// </summary>
Left,
/// <summary>
/// Content is right aligned.
/// </summary>
Right,
/// <summary>
/// Content is centered.
/// </summary>
Center
}
/// <summary>
/// Specifies content vertical alignment.
/// </summary>
public enum eContentVerticalAlignment
{
/// <summary>
/// Content is top aligned.
/// </summary>
Top,
/// <summary>
/// Content is bottom aligned.
/// </summary>
Bottom,
/// <summary>
/// Content is in the middle.
/// </summary>
Middle
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Drawing;
#if TREEGX
namespace DevComponents.Tree.TextMarkup
#elif DOTNETBAR
namespace DevComponents.UI.ContentManager
#endif
{
/// <summary>
/// Represents a content block interface.
/// </summary>
public interface IBlock
{
/// <summary>
/// Gets or sets the bounds of the content block.
/// </summary>
Rectangle Bounds {get;set;}
/// <summary>
/// Gets or sets whether content block is visible.
/// </summary>
bool Visible {get;set;}
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Text;
#if TREEGX
namespace DevComponents.Tree.TextMarkup
#elif DOTNETBAR
namespace DevComponents.UI.ContentManager
#endif
{
/// <summary>
/// Represents a extended content block interface for advanced layout information.
/// </summary>
public interface IBlockExtended : IBlock
{
bool IsBlockElement { get;}
bool IsNewLineAfterElement { get;}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Drawing;
#if TREEGX
namespace DevComponents.Tree.TextMarkup
#elif DOTNETBAR
namespace DevComponents.UI.ContentManager
#endif
{
/// <summary>
/// Represents interface for block layout.
/// </summary>
public interface IContentLayout
{
/// <summary>
/// Performs layout of the content block.
/// </summary>
/// <param name="containerBounds">Container bounds to layout content blocks in.</param>
/// <param name="contentBlocks">Content blocks to layout.</param>
/// <param name="blockLayout">Block layout manager that resizes the content blocks.</param>
/// <returns>The bounds of the content blocks within the container bounds.</returns>
Rectangle Layout(Rectangle containerBounds, IBlock[] contentBlocks, BlockLayoutManager blockLayout);
}
}

View File

@@ -0,0 +1,559 @@
using System;
using System.Collections;
using System.Drawing;
#if TREEGX
namespace DevComponents.Tree.TextMarkup
#elif DOTNETBAR
namespace DevComponents.UI.ContentManager
#endif
{
/// <summary>
/// Represents the serial content layout manager that arranges content blocks in series next to each other.
/// </summary>
public class SerialContentLayoutManager:IContentLayout
{
#region Events
/// <summary>
/// Occurs when X, Y position of next block is calcualted.
/// </summary>
public event LayoutManagerPositionEventHandler NextPosition;
/// <summary>
/// Occurs before new block is layed out.
/// </summary>
public event LayoutManagerLayoutEventHandler BeforeNewBlockLayout;
#endregion
#region Private Variables
private int m_BlockSpacing=0;
private bool m_FitContainerOversize=false;
private bool m_FitContainer=false;
private bool m_VerticalFitContainerWidth = false;
private eContentOrientation m_ContentOrientation=eContentOrientation.Horizontal;
private eContentAlignment m_ContentAlignment=eContentAlignment.Left;
private eContentVerticalAlignment m_ContentVerticalAlignment=eContentVerticalAlignment.Middle;
private eContentVerticalAlignment m_BlockLineAlignment = eContentVerticalAlignment.Middle;
private bool m_EvenHeight=false;
private bool m_MultiLine=false;
private bool m_RightToLeft = false;
#endregion
/// <summary>
/// Creates new instance of the class.
/// </summary>
public SerialContentLayoutManager()
{
}
#region IContentLayout Members
/// <summary>
/// Performs layout of the content block.
/// </summary>
/// <param name="containerBounds">Container bounds to layout content blocks in.</param>
/// <param name="contentBlocks">Content blocks to layout.</param>
/// <param name="blockLayout">Block layout manager that resizes the content blocks.</param>
/// <returns>The bounds of the content blocks within the container bounds.</returns>
public virtual Rectangle Layout(Rectangle containerBounds, IBlock[] contentBlocks, BlockLayoutManager blockLayout)
{
Rectangle blocksBounds=Rectangle.Empty;
Point position=containerBounds.Location;
ArrayList lines=new ArrayList();
lines.Add(new BlockLineInfo());
BlockLineInfo currentLine=lines[0] as BlockLineInfo;
bool switchToNewLine = false;
int visibleIndex = 0;
foreach(IBlock block in contentBlocks)
{
if(!block.Visible)
{
block.Bounds = Rectangle.Empty;
continue;
}
if (BeforeNewBlockLayout != null)
{
LayoutManagerLayoutEventArgs e = new LayoutManagerLayoutEventArgs(block, position, visibleIndex);
BeforeNewBlockLayout(this, e);
position = e.CurrentPosition;
if (e.CancelLayout)
continue;
}
visibleIndex++;
Size availableSize = containerBounds.Size;
bool isBlockElement = false;
bool isNewLineTriggger = false;
if (block is IBlockExtended)
{
IBlockExtended ex = block as IBlockExtended;
isBlockElement = ex.IsBlockElement;
isNewLineTriggger = ex.IsNewLineAfterElement;
}
if (!isBlockElement)
{
if (m_ContentOrientation == eContentOrientation.Horizontal)
availableSize.Width = (containerBounds.Right - position.X);
else
availableSize.Height = (containerBounds.Bottom - position.Y);
}
// Resize the content block
blockLayout.Layout(block, availableSize);
if(m_MultiLine && currentLine.Blocks.Count > 0)
{
if (m_ContentOrientation == eContentOrientation.Horizontal && position.X + block.Bounds.Width > containerBounds.Right || isBlockElement || switchToNewLine)
{
position.X=containerBounds.X;
position.Y+=(currentLine.LineSize.Height+m_BlockSpacing);
currentLine=new BlockLineInfo();
currentLine.Line=lines.Count;
lines.Add(currentLine);
}
else if (m_ContentOrientation == eContentOrientation.Vertical && position.Y + block.Bounds.Height > containerBounds.Bottom || isBlockElement || switchToNewLine)
{
position.Y=containerBounds.Y;
position.X+=(currentLine.LineSize.Width+m_BlockSpacing);
currentLine=new BlockLineInfo();
currentLine.Line=lines.Count;
lines.Add(currentLine);
}
}
if(m_ContentOrientation==eContentOrientation.Horizontal)
{
if(block.Bounds.Height>currentLine.LineSize.Height)
currentLine.LineSize.Height=block.Bounds.Height;
currentLine.LineSize.Width=position.X+block.Bounds.Width-containerBounds.X;
}
else if(m_ContentOrientation==eContentOrientation.Vertical)
{
if(block.Bounds.Width>currentLine.LineSize.Width)
currentLine.LineSize.Width=block.Bounds.Width;
currentLine.LineSize.Height=position.Y+block.Bounds.Height-containerBounds.Y;
}
currentLine.Blocks.Add(block);
block.Bounds=new Rectangle(position,block.Bounds.Size);
if(blocksBounds.IsEmpty)
blocksBounds=block.Bounds;
else
blocksBounds=Rectangle.Union(blocksBounds,block.Bounds);
switchToNewLine = isBlockElement | isNewLineTriggger;
position=GetNextPosition(block, position);
}
blocksBounds=AlignResizeBlocks(containerBounds, blocksBounds, lines);
if (m_RightToLeft)
blocksBounds = MirrorContent(containerBounds, blocksBounds, contentBlocks);
return blocksBounds;
}
#endregion
#region Internals
private Rectangle AlignResizeBlocks(Rectangle containerBounds,Rectangle blocksBounds,ArrayList lines)
{
Rectangle newBounds=Rectangle.Empty;
if(containerBounds.IsEmpty || blocksBounds.IsEmpty || ((BlockLineInfo)lines[0]).Blocks.Count==0)
return newBounds;
if(m_ContentAlignment==eContentAlignment.Left && m_ContentVerticalAlignment==eContentVerticalAlignment.Top &&
!m_FitContainer && !m_FitContainerOversize && !m_EvenHeight)
return blocksBounds;
Point[] offset=new Point[lines.Count];
Size[] sizeOffset=new Size[lines.Count];
foreach(BlockLineInfo lineInfo in lines)
{
if(m_ContentOrientation==eContentOrientation.Horizontal)
{
if(m_FitContainer && containerBounds.Width>lineInfo.LineSize.Width ||
m_FitContainerOversize && lineInfo.LineSize.Width>containerBounds.Width)
{
sizeOffset[lineInfo.Line].Width=(containerBounds.Width-lineInfo.LineSize.Width)/lineInfo.Blocks.Count;
blocksBounds.Width=containerBounds.Width;
}
}
else
{
if(m_FitContainer && containerBounds.Height>lineInfo.LineSize.Height ||
m_FitContainerOversize && lineInfo.LineSize.Height>containerBounds.Height)
{
sizeOffset[lineInfo.Line].Height=(containerBounds.Height-lineInfo.LineSize.Height)/lineInfo.Blocks.Count;
blocksBounds.Height=containerBounds.Height;
}
if (m_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width)
sizeOffset[lineInfo.Line].Width = (containerBounds.Width - lineInfo.LineSize.Width) / lines.Count;
}
if(m_ContentOrientation==eContentOrientation.Horizontal && !m_FitContainer)
{
if(containerBounds.Width>blocksBounds.Width && m_FitContainerOversize || !m_FitContainerOversize)
{
switch(m_ContentAlignment)
{
case eContentAlignment.Right:
offset[lineInfo.Line].X=containerBounds.Width-lineInfo.LineSize.Width;
break;
case eContentAlignment.Center:
offset[lineInfo.Line].X=(containerBounds.Width-lineInfo.LineSize.Width)/2;
break;
}
}
}
if(m_ContentOrientation==eContentOrientation.Vertical && !m_FitContainer)
{
if(containerBounds.Height>blocksBounds.Height && m_FitContainerOversize || !m_FitContainerOversize)
{
switch(m_ContentVerticalAlignment)
{
case eContentVerticalAlignment.Bottom:
offset[lineInfo.Line].Y=containerBounds.Height-lineInfo.LineSize.Height;
break;
case eContentVerticalAlignment.Middle:
offset[lineInfo.Line].Y=(containerBounds.Height-lineInfo.LineSize.Height)/2;
break;
}
}
}
}
if (m_VerticalFitContainerWidth && containerBounds.Width > blocksBounds.Width)
blocksBounds.Width = containerBounds.Width;
if(m_ContentOrientation==eContentOrientation.Horizontal)
{
foreach(BlockLineInfo lineInfo in lines)
{
foreach(IBlock block in lineInfo.Blocks)
{
if(!block.Visible)
continue;
Rectangle r=block.Bounds;
if(m_EvenHeight && lineInfo.LineSize.Height>0)
r.Height=lineInfo.LineSize.Height;
r.Offset(offset[lineInfo.Line]);
if(m_ContentVerticalAlignment==eContentVerticalAlignment.Middle)
{
// Takes care of offset rounding error when both content is vertically centered and blocks in line are centered
if (m_BlockLineAlignment == eContentVerticalAlignment.Middle)
r.Offset(0,((containerBounds.Height-blocksBounds.Height)+(lineInfo.LineSize.Height-r.Height))/2);
else
r.Offset(0,(containerBounds.Height-blocksBounds.Height)/2);
// Line alignment of the block
if (m_BlockLineAlignment == eContentVerticalAlignment.Bottom)
r.Offset(0, lineInfo.LineSize.Height - r.Height);
}
else if(m_ContentVerticalAlignment==eContentVerticalAlignment.Bottom)
r.Offset(0,containerBounds.Height-blocksBounds.Height);
// To avoid rounding offset errors when dividing this is split see upper part
if(m_ContentVerticalAlignment!=eContentVerticalAlignment.Middle)
{
// Line alignment of the block
if (m_BlockLineAlignment == eContentVerticalAlignment.Middle)
r.Offset(0, (lineInfo.LineSize.Height - r.Height) / 2);
else if (m_BlockLineAlignment == eContentVerticalAlignment.Bottom)
r.Offset(0, lineInfo.LineSize.Height - r.Height);
}
if(sizeOffset[lineInfo.Line].Width!=0)
{
r.Width+=sizeOffset[lineInfo.Line].Width;
offset[lineInfo.Line].X+=sizeOffset[lineInfo.Line].Width;
}
r.Height+=sizeOffset[lineInfo.Line].Height;
block.Bounds=r;
if(newBounds.IsEmpty)
newBounds=block.Bounds;
else
newBounds=Rectangle.Union(newBounds,block.Bounds);
}
// Adjust for left-over size adjustment for odd difference between container width and the total block width
if(sizeOffset[lineInfo.Line].Width!=0 && containerBounds.Width-(lineInfo.LineSize.Width+sizeOffset[lineInfo.Line].Width*lineInfo.Blocks.Count)!=0)
{
Rectangle r=((IBlock)lineInfo.Blocks[lineInfo.Blocks.Count-1]).Bounds;
r.Width+=containerBounds.Width-(lineInfo.LineSize.Width+sizeOffset[lineInfo.Line].Width*lineInfo.Blocks.Count);
((IBlock)lineInfo.Blocks[lineInfo.Blocks.Count-1]).Bounds=r;
}
}
}
else
{
foreach(BlockLineInfo lineInfo in lines)
{
foreach(IBlock block in lineInfo.Blocks)
{
if(!block.Visible)
continue;
Rectangle r=block.Bounds;
if(m_EvenHeight && lineInfo.LineSize.Width>0)
r.Width=lineInfo.LineSize.Width;
r.Offset(offset[lineInfo.Line]);
if(m_ContentAlignment==eContentAlignment.Center)
r.Offset(((containerBounds.Width-blocksBounds.Width)+(lineInfo.LineSize.Width-r.Width))/2,0); //r.Offset((containerBounds.Width-blocksBounds.Width)/2+(lineInfo.LineSize.Width-r.Width)/2,0);
else if(m_ContentAlignment==eContentAlignment.Right)
r.Offset((containerBounds.Width-blocksBounds.Width)+lineInfo.LineSize.Width-r.Width,0);
r.Width+=sizeOffset[lineInfo.Line].Width;
if(sizeOffset[lineInfo.Line].Height!=0)
{
r.Height+=sizeOffset[lineInfo.Line].Height;
offset[lineInfo.Line].Y+=sizeOffset[lineInfo.Line].Height;
}
block.Bounds=r;
if(newBounds.IsEmpty)
newBounds=block.Bounds;
else
newBounds=Rectangle.Union(newBounds,block.Bounds);
}
if(sizeOffset[lineInfo.Line].Height!=0 && containerBounds.Height-(lineInfo.LineSize.Height+sizeOffset[lineInfo.Line].Height*lineInfo.Blocks.Count)!=0)
{
Rectangle r=((IBlock)lineInfo.Blocks[lineInfo.Blocks.Count-1]).Bounds;
r.Height+=containerBounds.Height-(lineInfo.LineSize.Height+sizeOffset[lineInfo.Line].Height*lineInfo.Blocks.Count);
((IBlock)lineInfo.Blocks[lineInfo.Blocks.Count-1]).Bounds=r;
}
}
}
return newBounds;
}
private Point GetNextPosition(IBlock block, Point position)
{
if (NextPosition != null)
{
LayoutManagerPositionEventArgs e = new LayoutManagerPositionEventArgs();
e.Block = block;
e.CurrentPosition = position;
NextPosition(this, e);
if (e.Cancel)
return e.NextPosition;
}
if(m_ContentOrientation==eContentOrientation.Horizontal)
position.X+=block.Bounds.Width+m_BlockSpacing;
else
position.Y+=block.Bounds.Height+m_BlockSpacing;
return position;
}
private class BlockLineInfo
{
public BlockLineInfo() {}
public ArrayList Blocks=new ArrayList();
public Size LineSize=Size.Empty;
public int Line=0;
}
private Rectangle MirrorContent(Rectangle containerBounds, Rectangle blockBounds, IBlock[] contentBlocks)
{
int xOffset = (blockBounds.X - containerBounds.X);
if (blockBounds.Width < containerBounds.Width)
blockBounds.X = containerBounds.Right - ((blockBounds.X - containerBounds.X) + blockBounds.Width);
else if (blockBounds.Width > containerBounds.Width)
containerBounds.Width = blockBounds.Width;
foreach (IBlock block in contentBlocks)
{
if (!block.Visible)
continue;
Rectangle r = block.Bounds;
block.Bounds = new Rectangle(containerBounds.Right - ((r.X - containerBounds.X) + r.Width), r.Y, r.Width, r.Height);
}
return blockBounds;
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the spacing in pixels between content blocks. Default value is 0.
/// </summary>
public virtual int BlockSpacing
{
get {return m_BlockSpacing;}
set {m_BlockSpacing=value;}
}
/// <summary>
/// Gets or sets whether content blocks are forced to fit the container bounds if they
/// occupy more space than it is available by container. Default value is false.
/// </summary>
public virtual bool FitContainerOversize
{
get {return m_FitContainerOversize;}
set {m_FitContainerOversize=value;}
}
/// <summary>
/// Gets or sets whether content blocks are resized to fit the container bound if they
/// occupy less space than it is available by container. Default value is false.
/// </summary>
public virtual bool FitContainer
{
get {return m_FitContainer;}
set {m_FitContainer=value;}
}
/// <summary>
/// Gets or sets whether content blocks are resized (Width) to fit container bounds if they
/// occupy less space than the actual container width. Applies to the Vertical orientation only. Default value is false.
/// </summary>
public virtual bool VerticalFitContainerWidth
{
get { return m_VerticalFitContainerWidth; }
set { m_VerticalFitContainerWidth = value; }
}
/// <summary>
/// Gets or sets the content orientation. Default value is Horizontal.
/// </summary>
public virtual eContentOrientation ContentOrientation
{
get {return m_ContentOrientation;}
set {m_ContentOrientation=value;}
}
/// <summary>
/// Gets or sets the content vertical alignment. Default value is Middle.
/// </summary>
public virtual eContentVerticalAlignment ContentVerticalAlignment
{
get {return m_ContentVerticalAlignment;}
set {m_ContentVerticalAlignment=value;}
}
/// <summary>
/// Gets or sets the block line vertical alignment. Default value is Middle.
/// </summary>
public virtual eContentVerticalAlignment BlockLineAlignment
{
get { return m_BlockLineAlignment; }
set { m_BlockLineAlignment = value; }
}
/// <summary>
/// Gets or sets the content horiznontal alignment. Default value is Left.
/// </summary>
public virtual eContentAlignment ContentAlignment
{
get {return m_ContentAlignment;}
set {m_ContentAlignment=value;}
}
/// <summary>
/// Gets or sets whether all content blocks are resized so they have same height which is height of the talles content block. Default value is false.
/// </summary>
public virtual bool EvenHeight
{
get {return m_EvenHeight;}
set {m_EvenHeight=value;}
}
/// <summary>
/// Gets or sets whether content is wrapped into new line if it exceeds the width of the container.
/// </summary>
public bool MultiLine
{
get {return m_MultiLine;}
set {m_MultiLine=value;}
}
/// <summary>
/// Gets or sets whether layout is right-to-left.
/// </summary>
public bool RightToLeft
{
get { return m_RightToLeft; }
set { m_RightToLeft = value; }
}
#endregion
}
/// <summary>
/// Represents event arguments for SerialContentLayoutManager.NextPosition event.
/// </summary>
public class LayoutManagerPositionEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the block that is layed out.
/// </summary>
public IBlock Block = null;
/// <summary>
/// Gets or sets the current block position.
/// </summary>
public Point CurrentPosition = Point.Empty;
/// <summary>
/// Gets or sets the calculated next block position.
/// </summary>
public Point NextPosition = Point.Empty;
/// <summary>
/// Cancels default position calculation.
/// </summary>
public bool Cancel = false;
}
/// <summary>
/// Represents event arguments for the SerialContentLayoutManager layout events.
/// </summary>
public class LayoutManagerLayoutEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the reference block object.
/// </summary>
public IBlock Block = null;
/// <summary>
/// Gets or sets the position block will assume.
/// </summary>
public Point CurrentPosition = Point.Empty;
/// <summary>
/// Cancel the layout of the block, applies only to BeforeXXX layout event.
/// </summary>
public bool CancelLayout = false;
/// <summary>
/// Gets or sets the visibility index of the block.
/// </summary>
public int BlockVisibleIndex = 0;
/// <summary>
/// Creates new instance of the class and initializes it with default values.
/// </summary>
public LayoutManagerLayoutEventArgs(IBlock block, Point currentPosition, int visibleIndex)
{
this.Block = block;
this.CurrentPosition = currentPosition;
this.BlockVisibleIndex = visibleIndex;
}
}
/// <summary>
/// Delegate for SerialContentLayoutManager.NextPosition event.
/// </summary>
public delegate void LayoutManagerPositionEventHandler(object sender, LayoutManagerPositionEventArgs e);
/// <summary>
/// Delegate for the SerialContentLayoutManager layout events.
/// </summary>
public delegate void LayoutManagerLayoutEventHandler(object sender, LayoutManagerLayoutEventArgs e);
}

View File

@@ -0,0 +1,68 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Reflection;
#if TREEGX
namespace DevComponents.Tree.Design
#elif DOTNETBAR
namespace DevComponents.DotNetBar.Design
#endif
{
/// <summary>
/// Summary description for ColorSchemeColorConverter.
/// </summary>
public class ColorSchemeColorConverter:ColorConverter
{
/// <summary>
/// This member supports the .NET Framework infrastructure and is not intended to be used directly from your code.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that provides a format context. </param>
/// <param name="culture">The CultureInfo to use as the current culture. </param>
/// <param name="value">The Object to convert. </param>
/// <returns>An Object that represents the converted value.</returns>
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
Color color=Color.Empty;
if(value is string && value.ToString().StartsWith("CS."))
{
string propertyName=context.PropertyDescriptor.Name;
PropertyInfo property=context.Instance.GetType().GetProperty(propertyName+"SchemePart",BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if(property!=null)
{
property.SetValue(context.Instance,Enum.Parse(typeof(eColorSchemePart),value.ToString().Substring(4)),new object[]{});
color=(Color)context.PropertyDescriptor.GetValue(context.Instance);
}
}
else
return base.ConvertFrom(context, culture, value);
return color;
}
/// <summary>
/// Converts the given value object to the specified type.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that provides a format context. </param>
/// <param name="culture">A CultureInfo object. If a null reference (Nothing in Visual Basic) is passed, the current culture is assumed. </param>
/// <param name="value">The Object to convert.</param>
/// <param name="destinationType">The Type to convert the value parameter to. </param>
/// <returns>An Object that represents the converted value.</returns>
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if(context!=null && (destinationType == typeof(string)) && (value is Color))
{
string propertyName=context.PropertyDescriptor.Name;
PropertyInfo property=context.Instance.GetType().GetProperty(propertyName+"SchemePart",BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if(property!=null)
{
eColorSchemePart part = (eColorSchemePart)property.GetValue(context.Instance, new object[] {});
if(part!=eColorSchemePart.None)
return "CS." + part.ToString();
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}

View File

@@ -0,0 +1,271 @@
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace DevComponents.Tree.Design
{
/// <summary>
/// Summary description for ComponentNotLicensed.
/// </summary>
public class ComponentNotLicensed : System.Windows.Forms.Form
{
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.LinkLabel linkOrder;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.LinkLabel linkHome;
private System.Windows.Forms.LinkLabel linkEmail;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Timer timer1;
private System.ComponentModel.IContainer components;
public ComponentNotLicensed()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.label7 = new System.Windows.Forms.Label();
this.linkOrder = new System.Windows.Forms.LinkLabel();
this.label6 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.linkHome = new System.Windows.Forms.LinkLabel();
this.linkEmail = new System.Windows.Forms.LinkLabel();
this.button2 = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.Controls.Add(this.label7);
this.groupBox1.Controls.Add(this.linkOrder);
this.groupBox1.Controls.Add(this.label6);
this.groupBox1.Controls.Add(this.label5);
this.groupBox1.Location = new System.Drawing.Point(11, 54);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(294, 135);
this.groupBox1.TabIndex = 17;
this.groupBox1.TabStop = false;
//
// label7
//
this.label7.Location = new System.Drawing.Point(3, 104);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(285, 12);
this.label7.TabIndex = 3;
this.label7.Text = "Order at:";
this.label7.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// linkOrder
//
this.linkOrder.Location = new System.Drawing.Point(6, 116);
this.linkOrder.Name = "linkOrder";
this.linkOrder.Size = new System.Drawing.Size(280, 15);
this.linkOrder.TabIndex = 2;
this.linkOrder.TabStop = true;
this.linkOrder.Text = "http://www.devcomponents.com/treegx/order.html";
this.linkOrder.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.linkOrder.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkOrder_LinkClicked);
//
// label6
//
this.label6.Location = new System.Drawing.Point(9, 72);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(276, 31);
this.label6.TabIndex = 1;
this.label6.Text = "For pricing and licensing information please visit our web site. ";
//
// label5
//
this.label5.ForeColor = System.Drawing.Color.Maroon;
this.label5.Location = new System.Drawing.Point(8, 20);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(276, 52);
this.label5.TabIndex = 0;
this.label5.Text = "This component is not registered and it is provided for evaluation purposes only." +
" This message will not appear after you register the component.";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(10, 216);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(31, 16);
this.label4.TabIndex = 16;
this.label4.Text = "Web:";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(9, 200);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(40, 16);
this.label3.TabIndex = 14;
this.label3.Text = "E-Mail:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(7, 31);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(307, 16);
this.label2.TabIndex = 11;
this.label2.Text = "(c) 2005-2006 by DevComponents.com, All Rights Reserved";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label1.Location = new System.Drawing.Point(9, 7);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(236, 18);
this.label1.TabIndex = 9;
this.label1.Text = "DevComponents TreeGX Component";
//
// linkHome
//
this.linkHome.Location = new System.Drawing.Point(50, 215);
this.linkHome.Name = "linkHome";
this.linkHome.Size = new System.Drawing.Size(145, 16);
this.linkHome.TabIndex = 15;
this.linkHome.TabStop = true;
this.linkHome.Text = "www.devcomponents.com";
this.linkHome.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkHome_LinkClicked);
//
// linkEmail
//
this.linkEmail.Location = new System.Drawing.Point(49, 199);
this.linkEmail.Name = "linkEmail";
this.linkEmail.Size = new System.Drawing.Size(167, 16);
this.linkEmail.TabIndex = 13;
this.linkEmail.TabStop = true;
this.linkEmail.Text = "support@devcomponents.com";
this.linkEmail.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkEmail_LinkClicked);
//
// button2
//
this.button2.Location = new System.Drawing.Point(232, 240);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(72, 24);
this.button2.TabIndex = 12;
this.button2.Text = "Buy Now";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button1
//
this.button1.Enabled = false;
this.button1.Location = new System.Drawing.Point(152, 240);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(72, 24);
this.button1.TabIndex = 10;
this.button1.Text = "OK";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// timer1
//
this.timer1.Enabled = true;
this.timer1.Interval = 800;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// ComponentNotLicensed
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.Color.BlanchedAlmond;
this.ClientSize = new System.Drawing.Size(314, 273);
this.ControlBox = false;
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.linkHome);
this.Controls.Add(this.linkEmail);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.Name = "ComponentNotLicensed";
this.Text = "TreeGX License not found";
this.groupBox1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private void button2_Click(object sender, System.EventArgs e)
{
System.Diagnostics.Process.Start(linkOrder.Text);
}
private void button1_Click(object sender, System.EventArgs e)
{
this.Close();
}
private void linkHome_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("http://www.devcomponents.com");
}
private void linkOrder_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start(linkOrder.Text);
}
private void linkEmail_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start(linkEmail.Text);
}
private void timer1_Tick(object sender, System.EventArgs e)
{
timer1.Enabled=false;
button1.Enabled=true;
button1.Focus();
}
}
}

View File

@@ -0,0 +1,265 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used forserialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="groupBox1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="groupBox1.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="groupBox1.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="groupBox1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="groupBox1.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="groupBox1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label7.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="label7.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label7.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="linkOrder.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="linkOrder.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="linkOrder.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="label6.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="label6.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label6.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label5.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="label5.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label5.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label4.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="label4.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label4.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label3.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="label3.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label3.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="label2.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="label1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="label1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="linkHome.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="linkHome.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="linkHome.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="linkEmail.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="linkEmail.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="linkEmail.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="button2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="button2.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="button2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="button1.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="button1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="button1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="timer1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="timer1.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</data>
<data name="timer1.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>(Default)</value>
</data>
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="$this.Name">
<value>ComponentNotLicensed</value>
</data>
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>80</value>
</data>
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
</root>

View File

@@ -0,0 +1,150 @@
using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System.Windows.Forms;
using System.ComponentModel.Design;
namespace DevComponents.Tree.Design
{
/// <summary>
/// Represents type editor for ElementStyle used for Windows Forms design-time support.
/// </summary>
public class ElementStyleTypeEditor:System.Drawing.Design.UITypeEditor
{
#region Private Variables
private IWindowsFormsEditorService m_EditorService = null;
private const string OPTION_CREATE="Create style";
private const string OPTION_REMOVE="Delete selected style";
private const string OPTION_STYLES="Styles.";
#endregion
#region Internal Implementation
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context != null
&& context.Instance != null
&& provider != null)
{
ElementStyle es=value as ElementStyle;
m_EditorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
if(m_EditorService!=null)
{
TreeGX tree = null;
if(context.Instance is TreeGX)
tree=context.Instance as TreeGX;
else if(context.Instance is Node)
tree=((Node)context.Instance).TreeControl;
else if(context.Instance is Cell)
tree=((Cell)context.Instance).TreeControl;
ListBox lb=new ListBox();
if(es==null)
lb.Items.Add(OPTION_CREATE);
else
lb.Items.Add(OPTION_REMOVE);
if(tree!=null)
{
foreach(ElementStyle style in tree.Styles)
lb.Items.Add(style);
}
string[] styles = Enum.GetNames(typeof (ePredefinedElementStyle));
foreach(string s in styles)
lb.Items.Add(OPTION_STYLES + s);
lb.SelectedIndexChanged+=new EventHandler(this.SelectedChanged);
m_EditorService.DropDownControl(lb);
IDesignerHost dh=(IDesignerHost)provider.GetService(typeof(IDesignerHost));
if(lb.SelectedItem!=null && dh!=null)
{
if(lb.SelectedItem is ElementStyle)
{
value=lb.SelectedItem as ElementStyle;
}
else if(lb.SelectedItem!=null && lb.SelectedItem.ToString().StartsWith(OPTION_STYLES))
{
string styleName = lb.SelectedItem.ToString().Substring(OPTION_STYLES.Length);
Type t = typeof (NodeStyles);
ElementStyle predefinedStyle=t.GetProperty(styleName).GetValue(null, null) as ElementStyle;
ElementStyle newStyle=dh.CreateComponent(typeof(ElementStyle)) as ElementStyle;
newStyle.ApplyStyle(predefinedStyle);
newStyle.Description = styleName;
value = newStyle;
if(tree!=null)
{
IComponentChangeService cc = provider.GetService(typeof (IComponentChangeService)) as IComponentChangeService;
if(cc!=null)
cc.OnComponentChanging(tree, TypeDescriptor.GetProperties(tree)["Style"]);
tree.Styles.Add(value as ElementStyle);
if(cc!=null)
cc.OnComponentChanged(tree, TypeDescriptor.GetProperties(tree)["Style"],null,null);
}
}
else if(lb.SelectedItem!=null && lb.SelectedItem.ToString()==OPTION_CREATE)
{
value=dh.CreateComponent(typeof(ElementStyle)) as ElementStyle;
if(tree!=null)
{
IComponentChangeService cc = provider.GetService(typeof (IComponentChangeService)) as IComponentChangeService;
if(cc!=null)
cc.OnComponentChanging(tree, TypeDescriptor.GetProperties(tree)["Style"]);
tree.Styles.Add(value as ElementStyle);
if(cc!=null)
cc.OnComponentChanged(tree, TypeDescriptor.GetProperties(tree)["Style"],null,null);
}
}
else if(lb.SelectedItem!=null && lb.SelectedItem.ToString()==OPTION_REMOVE)
{
if(tree!=null)
{
IComponentChangeService cc = provider.GetService(typeof (IComponentChangeService)) as IComponentChangeService;
if(cc!=null)
cc.OnComponentChanging(tree, TypeDescriptor.GetProperties(tree)["Style"]);
if(tree!=null)
tree.Styles.Remove(value as ElementStyle);
if(cc!=null)
cc.OnComponentChanged(tree, TypeDescriptor.GetProperties(tree)["Style"],null,null);
if(tree.Styles.Count>0)
value = tree.Styles[0];
else
value=null;
}
else
value=null;
dh.DestroyComponent(es);
}
}
}
}
return value;
}
private void SelectedChanged(object sender, EventArgs e)
{
if(m_EditorService!=null)
m_EditorService.CloseDropDown();
}
/// <summary>
/// Gets the editor style used by the EditValue method.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param>
/// <returns>A UITypeEditorEditStyle value that indicates the style of editor used by EditValue. If the UITypeEditor does not support this method, then GetEditStyle will return None</returns>
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
if (context != null && context.Instance != null)
{
return UITypeEditorEditStyle.DropDown;
}
return base.GetEditStyle(context);
}
#endregion
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System.Windows.Forms;
using System.ComponentModel.Design;
namespace DevComponents.Tree.Design
{
/// <summary>
/// Represents type editor for NodeConnector used for Windows Forms design-time support.
/// </summary>
public class NodeConnectorTypeEditor:System.Drawing.Design.UITypeEditor
{
#region Private Variables
private IWindowsFormsEditorService m_EditorService = null;
private const string OPTION_CREATE="Create new connector";
private const string OPTION_REMOVE="Remove connector";
#endregion
#region Internal Implementation
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context != null
&& context.Instance != null
&& provider != null)
{
NodeConnector conn=value as NodeConnector;
m_EditorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
if(m_EditorService!=null)
{
ListBox lb=new ListBox();
lb.SelectedIndexChanged+=new EventHandler(this.SelectedChanged);
if(conn==null)
lb.Items.Add(OPTION_CREATE);
else
lb.Items.Add(OPTION_REMOVE);
m_EditorService.DropDownControl(lb);
IDesignerHost dh=(IDesignerHost)provider.GetService(typeof(IDesignerHost));
if(lb.SelectedItem!=null && dh!=null)
{
if(lb.SelectedItem.ToString()==OPTION_CREATE)
{
NodeConnector nd=dh.CreateComponent(typeof(NodeConnector)) as NodeConnector;
nd.LineWidth = 5;
value = nd;
}
else if(lb.SelectedItem.ToString()==OPTION_REMOVE)
{
value=null;
dh.DestroyComponent(conn);
}
}
}
}
return value;
}
private void SelectedChanged(object sender, EventArgs e)
{
if(m_EditorService!=null)
m_EditorService.CloseDropDown();
}
/// <summary>
/// Gets the editor style used by the EditValue method.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param>
/// <returns>A UITypeEditorEditStyle value that indicates the style of editor used by EditValue. If the UITypeEditor does not support this method, then GetEditStyle will return None</returns>
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
if (context != null && context.Instance != null)
{
return UITypeEditorEditStyle.DropDown;
}
return base.GetEditStyle(context);
}
#endregion
}
}

View File

@@ -0,0 +1,104 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System.Windows.Forms;
using System.ComponentModel.Design;
using System.Collections;
namespace DevComponents.Tree.Design
{
/// <summary>
/// Represents context menu type editor for Node.ContextMenu property.
/// </summary>
public class NodeContextMenuTypeEditor:System.Drawing.Design.UITypeEditor
{
#region Private Variables
private IWindowsFormsEditorService m_EditorService = null;
public static string DotNetBarPrefix="DotNetBar.";
#endregion
#region Internal Implementation
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context != null
&& context.Instance != null
&& provider != null)
{
m_EditorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
if(m_EditorService!=null)
{
ListBox lb=new ListBox();
object dotNetBarManager=null;
lb.SelectedIndexChanged+=new EventHandler(this.SelectedChanged);
IDesignerHost host = (IDesignerHost)provider.GetService(typeof(IDesignerHost));
foreach(IComponent component in host.Container.Components)
{
if(component is ContextMenu || component.GetType().FullName=="System.Windows.Forms.ContextMenuStrip")
{
lb.Items.Add(component);
}
if(component.GetType().FullName=="DevComponents.DotNetBar.DotNetBarManager")
{
dotNetBarManager=component;
IList contextMenus=component.GetType().InvokeMember("ContextMenus",
System.Reflection.BindingFlags.GetProperty, null, component, null) as IList;
if(contextMenus!=null)
{
foreach(object o in contextMenus)
{
string name=o.GetType().InvokeMember("Name", System.Reflection.BindingFlags.GetProperty, null, o, null).ToString();
if(name!=null)
{
lb.Items.Add(DotNetBarPrefix+name);
}
}
}
}
}
m_EditorService.DropDownControl(lb);
if(lb.SelectedItem!=null)
{
if(lb.SelectedItem.ToString().StartsWith(DotNetBarPrefix))
{
Node node=context.Instance as Node;
if(node!=null && node.TreeControl!=null)
{
TypeDescriptor.GetProperties(node.TreeControl)["DotNetBarManager"].SetValue(node.TreeControl, dotNetBarManager);
}
}
return lb.SelectedItem;
}
}
}
return value;
}
private void SelectedChanged(object sender, EventArgs e)
{
if(m_EditorService!=null)
m_EditorService.CloseDropDown();
}
/// <summary>
/// Gets the editor style used by the EditValue method.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param>
/// <returns>A UITypeEditorEditStyle value that indicates the style of editor used by EditValue. If the UITypeEditor does not support this method, then GetEditStyle will return None</returns>
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
if (context != null && context.Instance != null)
{
return UITypeEditorEditStyle.DropDown;
}
return base.GetEditStyle(context);
}
#endregion
}
}

View File

@@ -0,0 +1,195 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace DevComponents.Tree.Design
{
/// <summary>
/// Represents Windows Forms designer for Node object.
/// </summary>
public class NodeDesigner:ComponentDesigner
{
/// <summary>
/// Initializes designer with given component.
/// </summary>
/// <param name="component">Component to initalize designer with.</param>
public override void Initialize(IComponent component)
{
base.Initialize(component);
if(!component.Site.DesignMode)
return;
ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService));
if(ss!=null)
ss.SelectionChanged+=new EventHandler(OnSelectionChanged);
Node n=component as Node;
if(n!=null)
this.Visible=n.Visible;
}
private void OnSelectionChanged(object sender, EventArgs e)
{
ISelectionService ss = (ISelectionService)sender;
if (this.Component != null && ss.PrimarySelection != this.Component)
{
Node node = this.Component as Node;
if (ss.PrimarySelection is Node)
{
Node selected = ss.PrimarySelection as Node;
if (selected.TreeControl != node.TreeControl)
{
node.TreeControl.SelectedNode = null;
}
}
else if (node != null && node.TreeControl != null)
node.TreeControl.SelectedNode = null;
}
}
protected override void PreFilterProperties(System.Collections.IDictionary properties)
{
base.PreFilterProperties(properties);
properties["Visible"] = TypeDescriptor.CreateProperty(typeof(NodeDesigner),(PropertyDescriptor)properties["Visible"], new Attribute[]
{
new DefaultValueAttribute(true),
new BrowsableAttribute(true),
new CategoryAttribute("Layout")});
// properties["HostedControl"] = TypeDescriptor.CreateProperty(typeof(NodeDesigner),(PropertyDescriptor)properties["HostedControl"], new Attribute[]
// {
// new DefaultValueAttribute(null),
// new BrowsableAttribute(true),
// new CategoryAttribute("Behavior"),
// new DescriptionAttribute("Indicates control hosted inside of the cell.")});
}
/// <summary>
/// Gets or sets whether item is visible.
/// </summary>
[DefaultValue(true),Browsable(true),Category("Layout"),Description("Gets or sets whether node is visible.")]
public bool Visible
{
get
{
return (bool)ShadowProperties["Visible"];
}
set
{
// this value is not passed to the actual control
this.ShadowProperties["Visible"] = value;
}
}
// /// <summary>
// /// Gets or sets whether item is visible.
// /// </summary>
// [DefaultValue(null),Browsable(true),Category("Behavior"),Description("Indicates control hosted inside of the cell.")]
// public Control HostedControl
// {
// get
// {
// Node node = this.Component as Node;
// return node.HostedControl;
// }
// set
// {
// Node node = this.Component as Node;
// node.HostedControl = value;
// if(value!=null)
// {
// IDesignerHost dh = this.GetService(typeof (IDesignerHost)) as IDesignerHost;
// if(dh!=null)
// {
// TreeGXDesigner ds = dh.GetDesigner(node.TreeControl) as TreeGXDesigner;
// if(ds!=null)
// ds.HookControl(value);
// }
// }
// }
// }
/// <summary>Returns design-time commands applicable to this designer.</summary>
public override DesignerVerbCollection Verbs
{
get
{
DesignerVerb[] verbs = new DesignerVerb[]
{
new DesignerVerb("Create Child Node", new EventHandler(CreateNode))
};
return new DesignerVerbCollection(verbs);
}
}
private void CreateNode(object sender, EventArgs e)
{
Node node=CreateNode(this.Component as Node);
if(node!=null)
{
ISelectionService sel = this.GetService(typeof (ISelectionService)) as ISelectionService;
ArrayList list=new ArrayList(1);
list.Add(node);
if(sel!=null)
{
sel.SetSelectedComponents(list, SelectionTypes.Primary);
node.TreeControl.SelectedNode = node;
}
}
}
private Node CreateNode(Node parentNode)
{
IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost));
if(dh==null)
return null;
Node node=null;
TreeGX tree=((Node)this.Component).TreeControl;
tree.BeginUpdate();
try
{
IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
if(change!=null)
{
if(parentNode!=null)
change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(parentNode).Find("Nodes",true));
else
change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true));
}
node=dh.CreateComponent(typeof(Node)) as Node;
if(node!=null)
{
node.Text=node.Name;
node.Expanded = true;
if(parentNode==null)
tree.Nodes.Add(node);
else
{
parentNode.Nodes.Add(node);
parentNode.Expand();
TypeDescriptor.GetProperties(node)["Style"].SetValue(node,parentNode.Style);
}
if(change!=null)
{
if(parentNode!=null)
change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(parentNode).Find("Nodes",true),null,null);
else
change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true),null,null);
}
}
}
finally
{
tree.EndUpdate();
}
return node;
}
}
}

View File

@@ -0,0 +1,854 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace DevComponents.Tree.Design
{
/// <summary>
/// Represents windows forms designer for the control.
/// </summary>
public class TreeGXDesigner:ParentControlDesigner
{
#region Private Variables
// private Point m_MouseDownPosition=Point.Empty;
// private bool m_IgnoreMouseUp=false;
// private bool m_Capture=false;
private bool m_DragDropStarted=false;
const string TEMP_NAME="tempDragDropItem";
const int WM_RBUTTONDOWN=0x0204;
const int WM_LBUTTONDOWN=0x0201;
// const int WM_LBUTTONUP=0x0202;
// const int WM_RBUTTONUP=0x0205;
// const int WM_MOUSEMOVE=0x0200;
const int WM_LBUTTONDBLCLK=0x0203;
private Timer m_TimerAdded=null;
private Timer m_TimerDragDrop=null;
private bool m_DragLeave=false;
private bool m_ControlRemoved=false;
private DateTime m_JustAdded=DateTime.MinValue;
private bool m_NewControlAdded=false;
private Point m_MouseDownPoint=Point.Empty;
#endregion
#region Designer Implementation
/// <summary>Initializes designer with given component.</summary>
/// <param name="component">Component to initialize designer with.</param>
public override void Initialize(IComponent component)
{
base.Initialize(component);
if(!component.Site.DesignMode)
return;
ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService));
if(ss!=null)
ss.SelectionChanged+=new EventHandler(OnSelectionChanged);
// If our component is removed we need to clean-up
IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService));
if(cc!=null)
{
cc.ComponentRemoving+=new ComponentEventHandler(this.OnComponentRemoving);
}
if(component is Control)
{
((Control)component).ControlAdded+=new ControlEventHandler(this.ControlAdded);
((Control)component).ControlRemoved+=new ControlEventHandler(this.ControlRemoved);
}
#if !TRIAL
IDesignerHost dh = this.GetService(typeof (IDesignerHost)) as IDesignerHost;
if(dh!=null)
dh.LoadComplete+=new EventHandler(dh_LoadComplete);
#endif
}
protected override void Dispose(bool disposing)
{
ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService));
if(ss!=null)
ss.SelectionChanged-=new EventHandler(OnSelectionChanged);
// If our component is removed we need to clean-up
IComponentChangeService cc=(IComponentChangeService)GetService(typeof(IComponentChangeService));
if(cc!=null)
cc.ComponentRemoving-=new ComponentEventHandler(this.OnComponentRemoving);
if(this.Control!=null)
{
this.Control.ControlAdded-=new ControlEventHandler(this.ControlAdded);
this.Control.ControlRemoved-=new ControlEventHandler(this.ControlRemoved);
}
base.Dispose (disposing);
}
internal void HookControl(Control c)
{
this.HookChildControls(c);
}
// public override DesignerVerbCollection Verbs
// {
// get
// {
// DesignerVerb[] verbs = new DesignerVerb[]
// {
// new DesignerVerb("Create Node", new EventHandler(CreateNode))};
// return new DesignerVerbCollection(verbs);
// }
// }
public override void InitializeNewComponent(IDictionary defaultValues)
{
base.InitializeNewComponent(defaultValues);
SetDefaults();
}
private void SetDefaults()
{
CreateNode(null,true);
IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost));
if(dh==null)
return;
Utilites.InitializeTree(this.Control as TreeGX,new ComponentFactory(dh));
#if !TRIAL
string key=GetLicenseKey();
TreeGX tree=this.Control as TreeGX;
tree.LicenseKey=key;
#endif
}
private Node CreateNode(Node parentNode, bool addToCollections)
{
TreeGX tree=this.Control as TreeGX;
IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost));
if(dh==null)
return null;
Node node=null;
tree.BeginUpdate();
try
{
IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
if(addToCollections)
{
if(change!=null)
{
if(parentNode!=null)
change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(parentNode).Find("Nodes",true));
else
change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true));
}
}
node=dh.CreateComponent(typeof(Node)) as Node;
if(node!=null)
{
node.Text=node.Name;
node.Expanded = true;
if(addToCollections)
{
if(parentNode==null)
tree.Nodes.Add(node);
else
parentNode.Nodes.Add(node);
if(change!=null)
{
if(parentNode!=null)
change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(parentNode).Find("Nodes",true),null,null);
else
change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true),null,null);
}
}
}
}
finally
{
tree.EndUpdate();
}
return node;
}
private void OnSelectionChanged(object sender,EventArgs e)
{
ISelectionService ss = (ISelectionService)sender;
if(ss.PrimarySelection==this.Component)
{
TreeGX tree=this.Control as TreeGX;
tree.SelectedNode=null;
}
}
/// <summary>Called when component is about to be removed from designer.</summary>
/// <param name="sender">Event sender.</param>
/// <param name="e">Event arguments.</param>
public void OnComponentRemoving(object sender,ComponentEventArgs e)
{
if(e.Component==this.Component)
{
IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost));
if(dh==null)
return;
ArrayList list = new ArrayList(this.AssociatedComponents);
foreach(IComponent c in list)
dh.DestroyComponent(c);
}
else if(e.Component is Node && ((Node)e.Component).TreeControl==this.Control)
{
OnNodeRemoving(e.Component as Node);
}
}
private void OnNodeRemoving(Node node)
{
IComponentChangeService cc=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost));
if(node.Parent!=null)
{
Node parent=node.Parent;
if(cc!=null)
cc.OnComponentChanging(parent,TypeDescriptor.GetProperties(parent)["Nodes"]);
node.Remove();
if(cc!=null)
cc.OnComponentChanged(parent,TypeDescriptor.GetProperties(parent)["Nodes"],null,null);
}
if(node.Nodes.Count>0)
{
Node[] nodes=new Node[node.Nodes.Count];
node.Nodes.CopyTo(nodes);
foreach(Node n in nodes)
{
n.Remove();
if(n.ParentConnector!=null && dh!=null)
dh.DestroyComponent(n.ParentConnector);
if(dh!=null)
dh.DestroyComponent(n);
}
}
this.RecalcLayout();
}
/// <summary>
/// Returns all components associated with this control
/// </summary>
public override ICollection AssociatedComponents
{
get
{
ArrayList c=new ArrayList(base.AssociatedComponents);
TreeGX tree=this.Control as TreeGX;
if(tree!=null)
{
foreach(Node node in tree.Nodes)
GetNodesRecursive(node,c);
foreach(ElementStyle style in tree.Styles)
c.Add(style);
if(tree.NodesConnector!=null)
c.Add(tree.NodesConnector);
if(tree.RootConnector!=null)
c.Add(tree.RootConnector);
if(tree.LinkConnector!=null)
c.Add(tree.LinkConnector);
if(tree.SelectedPathConnector!=null)
c.Add(tree.SelectedPathConnector);
}
return c;
}
}
private void GetNodesRecursive(Node parent,ArrayList c)
{
c.Add(parent);
if(parent.ParentConnector!=null)
c.Add(parent.ParentConnector);
foreach(Node node in parent.Nodes)
{
c.Add(node);
if (node.Cells.Count > 1)
{
for (int i = 1; i < node.Cells.Count; i++)
{
c.Add(node.Cells[i]);
}
}
if (node.NodesColumns.Count > 0)
{
foreach (ColumnHeader ch in node.NodesColumns)
{
c.Add(ch);
}
}
GetNodesRecursive(node,c);
}
}
/// <summary>
/// Selection support for items on container.
/// </summary>
protected override void WndProc(ref Message m)
{
switch(m.Msg)
{
case WM_LBUTTONDOWN:
{
if(OnMouseDown(ref m,MouseButtons.Left))
return;
break;
}
case WM_RBUTTONDOWN:
{
if(OnMouseDown(ref m,MouseButtons.Right))
return;
break;
}
// case WM_LBUTTONUP:
// {
// if(OnMouseUp(ref m,MouseButtons.Left))
// return;
// break;
// }
// case WM_RBUTTONUP:
// {
// if(OnMouseUp(ref m,MouseButtons.Right))
// return;
// break;
// }
// case WM_MOUSEMOVE:
// {
// if(OnMouseMove(ref m))
// return;
// break;
// }
case WM_LBUTTONDBLCLK:
{
if(OnMouseDoubleClick())
return;
break;
}
}
base.WndProc(ref m);
}
private bool OnMouseDoubleClick()
{
bool processed=false;
ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService));
if(selection.PrimarySelection is Node && ((Node)selection.PrimarySelection).TreeControl==this.Control)
{
IDesignerHost host=(IDesignerHost) this.GetService(typeof(IDesignerHost));
if(host!=null)
{
IDesigner designer=host.GetDesigner(selection.PrimarySelection as IComponent);
if(designer!=null)
{
designer.DoDefaultAction();
processed=true;
}
}
}
return processed;
}
protected virtual bool OnMouseDown(ref Message m, MouseButtons button)
{
TreeGX tree=this.Control as TreeGX;
if(tree==null)
return false;
Point pos=tree.PointToClient(System.Windows.Forms.Control.MousePosition);
//m_MouseDownPosition=pos;
Node node=tree.GetNodeAt(pos);
if(node!=null && button==MouseButtons.Right)
{
ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService));
ArrayList arr=new ArrayList(1);
arr.Add(node);
selection.SetSelectedComponents(arr,SelectionTypes.Primary);
tree.SelectedNode=node;
this.OnContextMenu(System.Windows.Forms.Control.MousePosition.X,System.Windows.Forms.Control.MousePosition.Y);
return true;
}
return false;
}
/// <summary>Specifies selection rules for designer.</summary>
public override SelectionRules SelectionRules
{
get
{
return (SelectionRules.AllSizeable | SelectionRules.Moveable | SelectionRules.Visible);
}
}
#endregion
#region Drag & Drop External Control Support
private void DestroyComponent(IComponent c)
{
IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost));
if(dh==null)
return;
dh.DestroyComponent(c);
}
private void RecalcLayout()
{
TreeGX tree = this.Control as TreeGX;
if(tree!=null)
{
tree.RecalcLayout();
tree.Refresh();
}
}
private void ControlAdded(object sender, ControlEventArgs e)
{
if(!m_NewControlAdded)
{
if(!m_NewControlAdded)
{
if(!OnControlAdded(e))
return;
}
else
return;
}
m_TimerAdded=new Timer();
m_TimerAdded.Tick+=new EventHandler(this.TimerTick);
m_TimerAdded.Interval=50;
m_TimerAdded.Enabled=true;
m_TimerAdded.Start();
m_NewControlAdded=false;
}
/// <summary>
/// Called after control has been added to container but not through drag & drop. Control added could also be
/// internal control by the bar container.
/// </summary>
/// <param name="e">Event arguments</param>
/// <returns>true if acted upon this new control otherwise false.</returns>
protected virtual bool OnControlAdded(ControlEventArgs e)
{
return false;
}
private void ControlRemoved(object sender, ControlEventArgs e)
{
IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost));
if(dh==null || dh.Loading)
return;
if(m_JustAdded!=DateTime.MinValue && DateTime.Now.Subtract(m_JustAdded).Seconds<2)
{
m_JustAdded=DateTime.MinValue;
return;
}
m_JustAdded=DateTime.MinValue;
if(m_DragLeave)
ControlRemoved(e.Control);
else if(m_TimerDragDrop!=null)
m_ControlRemoved=true;
else
{
ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService));
if(ss!=null && ss.PrimarySelection==e.Control && Utilites.FindNodeForControl(this.Control as TreeGX, e.Control)!=null)
{
ControlRemoved(e.Control);
}
}
}
private void ControlRemoved(Control control)
{
TreeGX tree = this.Control as TreeGX;
if(control!=null)
{
Node node=Utilites.FindNodeForControl(tree,control);
if(node!=null)
{
if(m_DragDropStarted)
{
tree.InternalDragLeave();
m_DragDropStarted = false;
}
if(node.Parent!=null)
{
Node parent=node.Parent;
IComponentChangeService cc = this.GetService(typeof (IComponentChangeService)) as IComponentChangeService;
if(cc!=null)
cc.OnComponentChanging(parent, TypeDescriptor.GetProperties(parent)["Nodes"]);
node.Remove();
if(cc!=null)
cc.OnComponentChanged(parent, TypeDescriptor.GetProperties(parent)["Nodes"],null,null);
}
this.DestroyComponent(node);
this.RecalcLayout();
}
}
}
private void TimerTick(object sender, EventArgs e)
{
m_TimerAdded.Stop();
m_TimerAdded.Enabled=false;
m_TimerAdded=null;
this.RecalcLayout();
ISelectionService sel=(ISelectionService)this.GetService(typeof(ISelectionService));
if(sel!=null && sel.PrimarySelection is Control && this.Control.Controls.Contains((Control)sel.PrimarySelection))
{
IComponentChangeService cc=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
cc.OnComponentChanged(sel.PrimarySelection,null,null,null);
}
}
private void TimerTickDragDrop(object sender, EventArgs e)
{
Point p=this.Control.PointToClient(System.Windows.Forms.Control.MousePosition);
if(this.Control.Bounds.Contains(p))
m_DragLeave=false;
else
m_DragLeave=true;
if(System.Windows.Forms.Control.MouseButtons!=MouseButtons.Left)
{
m_TimerDragDrop.Enabled=false;
m_TimerDragDrop.Stop();
m_TimerDragDrop.Tick-=new EventHandler(TimerTickDragDrop);
m_TimerDragDrop.Dispose();
m_TimerDragDrop=null;
if(m_ControlRemoved)
{
m_ControlRemoved=false;
ISelectionService sel=this.GetService(typeof(ISelectionService)) as ISelectionService;
if(sel!=null && sel.PrimarySelection is Control)
ControlRemoved((Control)sel.PrimarySelection);
}
}
}
protected override void OnDragLeave(EventArgs e)
{
if(m_DragDropStarted)
{
TreeGX tree=this.Control as TreeGX;
tree.InternalDragLeave();
m_DragDropStarted = false;
}
base.OnDragLeave (e);
}
protected override void OnDragOver(DragEventArgs de)
{
TreeGX tree=this.Control as TreeGX;
if(tree==null)
{
base.OnDragOver(de);
return;
}
if(m_DragDropStarted)
{
DragEventArgs d=new DragEventArgs(null,de.KeyState,de.X,de.Y,DragDropEffects.All,DragDropEffects.Move);
tree.InternalDragOver(d);
de.Effect=DragDropEffects.Move;
return;
}
ISelectionService sel=(ISelectionService)this.GetService(typeof(ISelectionService));
if(sel!=null && sel.PrimarySelection!=this.Component)
{
if(sel.PrimarySelection is Control && this.Control.Controls.Contains((Control)sel.PrimarySelection))
{
Node node=Utilites.FindNodeForControl(tree,sel.PrimarySelection as Control);
if(node!=null)
{
if(tree.StartDragDrop(node))
{
if(m_TimerDragDrop==null)
{
m_TimerDragDrop=new Timer();
m_TimerDragDrop.Tick+=new EventHandler(this.TimerTickDragDrop);
m_TimerDragDrop.Interval=100;
m_TimerDragDrop.Enabled=true;
m_TimerDragDrop.Start();
}
m_DragDropStarted = true;
}
}
return;
}
else if(sel.SelectionCount>1)
{
de.Effect=DragDropEffects.None;
return;
}
else if(sel.PrimarySelection is Control && ((Control)sel.PrimarySelection).Parent!=null)
{
// New control being added to the container
Node node=new Node();
node.Name=TEMP_NAME;
node.Text = ((Control) sel.PrimarySelection).Name;
if(tree.StartDragDrop(node))
m_DragDropStarted = true;
}
}
base.OnDragOver (de);
}
protected override void OnDragDrop(DragEventArgs de)
{
TreeGX tree=this.Control as TreeGX;
if(tree==null)
{
base.OnDragDrop(de);
return;
}
ISelectionService sel=(ISelectionService)this.GetService(typeof(ISelectionService));
if(sel!=null && sel.PrimarySelection is Control && this.Control.Controls.Contains((Control)sel.PrimarySelection))
{
de.Effect=DragDropEffects.Move;
tree.InternalDragDrop(new DragEventArgs(null,0,0,0,DragDropEffects.Move,DragDropEffects.All));
}
else
{
if(sel.SelectionCount>1)
{
de.Effect=DragDropEffects.None;
return;
}
else
{
Node node = tree.GetDragNode();
if(node!=null && node.Tag is Node && ((Node)node.Tag).Name==TEMP_NAME)
{
m_JustAdded=DateTime.Now;
Node dragNode=CreateNode(null,false);
TypeDescriptor.GetProperties(dragNode)["HostedControl"].SetValue(dragNode,sel.PrimarySelection as Control);
TypeDescriptor.GetProperties(dragNode)["Text"].SetValue(dragNode,dragNode.HostedControl.Name);
node.Tag = dragNode;
tree.InternalDragDrop(new DragEventArgs(null,0,0,0,DragDropEffects.Move,DragDropEffects.All));
m_NewControlAdded=true;
m_DragDropStarted = false;
}
}
}
base.OnDragDrop(de);
}
#endregion
#region Drag & Drop support
/// <summary>
/// Called after node has been selected by designer as response to mouse action
/// </summary>
/// <param name="node">Node that is selected</param>
protected virtual void OnNodeSelected(Node node)
{
}
/// <summary>
/// Returns whether specified node can be dragged and dropped
/// </summary>
/// <param name="node">Node to verify</param>
/// <returns>true if node can be dragged and dropped</returns>
protected virtual bool CanDragNode(Node node)
{
return true;
}
protected override void OnMouseDragBegin(int x, int y)
{
TreeGX tree=this.Control as TreeGX;
if(tree==null)
{
base.OnMouseDragBegin(x,y);
return;
}
Point pos=tree.PointToClient(new Point(x,y));
Node node = tree.GetNodeAt(pos);
if(node!=null)
{
Rectangle expandedRect=Display.NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds,node,tree.NodeDisplay.Offset);
if(!expandedRect.IsEmpty && expandedRect.Contains(pos))
{
node.Expanded=!node.Expanded;
return;
}
ISelectionService selection = (ISelectionService) this.GetService(typeof(ISelectionService));
if(selection!=null)
{
ArrayList arr=new ArrayList(1);
arr.Add(node);
selection.SetSelectedComponents(arr,SelectionTypes.Primary);
OnNodeSelected(node);
}
tree.SelectedNode = node;
}
else
tree.SelectedNode = null;
if(node==null || !CanDragNode(node))
{
if(node==null)
base.OnMouseDragBegin(x,y);
else
this.Control.Capture = true; // Does same as base implementation
return;
}
m_MouseDownPoint=new Point(x,y);
this.Control.Capture = true;
}
protected override void OnMouseDragMove(int x, int y)
{
TreeGX tree=this.Control as TreeGX;
if(!m_MouseDownPoint.IsEmpty && tree.SelectedNode!=null)
{
if(Math.Abs(m_MouseDownPoint.X-x)>=SystemInformation.DragSize.Width || Math.Abs(m_MouseDownPoint.Y-y)>=SystemInformation.DragSize.Height)
{
tree.StartDragDrop(tree.SelectedNode);
m_MouseDownPoint=Point.Empty;
m_DragDropStarted=true;
return;
}
}
if(m_DragDropStarted)
{
DragEventArgs de=new DragEventArgs(null,(int)Control.ModifierKeys,x,y,DragDropEffects.All,DragDropEffects.Move);
tree.InternalDragOver(de);
}
}
protected override void OnMouseDragEnd(bool cancel)
{
this.Control.Capture = false;
Cursor.Clip = Rectangle.Empty;
TreeGX tree=this.Control as TreeGX;
if(m_DragDropStarted)
{
if(tree!=null && tree.IsDragDropInProgress)
{
if(cancel)
tree.InternalDragLeave();
else if(tree.GetDragNode()!=null)
{
IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
Node dragNode=tree.GetDragNode().Tag as Node;
if(dragNode!=null)
{
Node newParent=tree.GetDragNode().Parent;
Node parent=dragNode.Parent;
if(change!=null)
{
if(parent!=null)
change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(parent).Find("Nodes",true));
else
change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true));
if(newParent!=null)
change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(newParent).Find("Nodes",true));
else
change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true));
}
tree.InternalDragDrop(new DragEventArgs(null,0,0,0,DragDropEffects.None,DragDropEffects.None));
newParent = dragNode.Parent;
if(change!=null)
{
if(parent!=null)
change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(parent).Find("Nodes",true),null,null);
else
change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true),null,null);
if(newParent!=null)
change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(newParent).Find("Nodes",true),null,null);
else
change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true),null,null);
}
}
}
}
cancel=true;
}
else
{
if(tree.SelectedNode!=null)
cancel=true;
}
m_DragDropStarted = false;
base.OnMouseDragEnd(cancel);
}
#endregion
#region Licensing Stuff
#if !TRIAL
private string GetLicenseKey()
{
string key="";
Microsoft.Win32.RegistryKey regkey=Microsoft.Win32.Registry.LocalMachine;
regkey=regkey.OpenSubKey("Software\\DevComponents\\Licenses",false);
if(regkey!=null)
{
object keyValue=regkey.GetValue("DevComponents.Tree.TreeGX");
if(keyValue!=null)
key=keyValue.ToString();
}
return key;
}
private void dh_LoadComplete(object sender, EventArgs e)
{
IDesignerHost dh = this.GetService(typeof (IDesignerHost)) as IDesignerHost;
if(dh!=null)
dh.LoadComplete-=new EventHandler(dh_LoadComplete);
string key=GetLicenseKey();
TreeGX tree=this.Control as TreeGX;
if(key!="" && tree!=null && tree.LicenseKey=="" && tree.LicenseKey!=key)
TypeDescriptor.GetProperties(tree)["LicenseKey"].SetValue(tree,key);
}
#endif
#endregion
}
}

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DocumentXComments Version="4.00" DocType="dx.Net" Moniker="obj\Debug\DevComponents.TreeGX.dll" ShowInherited="False" Template="" RelatedProject="TreeGXDocumentation.dxp"/>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,171 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represents cell display class.
/// </summary>
internal class CellDisplay
{
public CellDisplay()
{
}
public static void PaintCell(NodeCellRendererEventArgs ci)
{
if(ci.Cell.CheckBoxVisible)
CellDisplay.PaintCellCheckBox(ci);
if(!ci.Cell.Images.LargestImageSize.IsEmpty)
CellDisplay.PaintCellImage(ci);
CellDisplay.PaintText(ci);
}
public static void PaintCellCheckBox(NodeCellRendererEventArgs ci)
{
if(!ci.Cell.CheckBoxVisible)
return;
Rectangle r=ci.Cell.CheckBoxBoundsRelative;
r.Offset(ci.CellOffset);
System.Windows.Forms.ButtonState state=System.Windows.Forms.ButtonState.Normal;
if(ci.Cell.Checked)
state=System.Windows.Forms.ButtonState.Checked;
System.Windows.Forms.ControlPaint.DrawCheckBox(ci.Graphics,r,state);
}
public static void PaintCellImage(NodeCellRendererEventArgs ci)
{
if(ci.Cell.Images.LargestImageSize.IsEmpty)
return;
Rectangle r=ci.Cell.ImageBoundsRelative;
r.Offset(ci.CellOffset);
Image image = CellDisplay.GetCellImage(ci.Cell);
if(image!=null)
{
Size imageSize = Dpi.Size(image.Size);
ci.Graphics.DrawImage(image,r.X+(r.Width-imageSize.Width)/2,
r.Y+(r.Height-imageSize.Height)/2, imageSize.Width, imageSize.Height);
}
}
public static void PaintText(NodeCellRendererEventArgs ci)
{
Cell cell=ci.Cell;
if(cell.HostedControl==null && (cell.Text=="" || ci.Style.TextColor.IsEmpty) || cell.TextContentBounds.IsEmpty )
return;
Rectangle bounds=ci.Cell.TextContentBounds;
bounds.Offset(ci.CellOffset);
if(cell.HostedControl!=null)
{
// if(ci.Graphics.Transform!=null)
// {
// Point[] p=new Point[] {new Point(bounds.X, bounds.Y), new Point(bounds.Right, bounds.Bottom)};
// ci.Graphics.Transform.TransformPoints(p);
// bounds = new Rectangle(p[0].X, p[0].Y, p[1].X-p[0].X, p[1].Y-p[0].Y);
// }
// if(cell.HostedControl.Bounds!=bounds)
// {
// cell.IgnoreHostedControlSizeChange = true;
// cell.HostedControl.Bounds=bounds;
// cell.IgnoreHostedControlSizeChange = false;
// }
if(!cell.HostedControl.Visible)
cell.HostedControl.Visible = true;
return;
}
Font font=ci.Style.Font;
bounds.Inflate(1,1);
if (cell.TextMarkupBody == null)
TextDrawing.DrawString(ci.Graphics , cell.Text, font, ci.Style.TextColor, bounds, ci.Style.TextFormat);
else
{
TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(ci.Graphics, font, ci.Style.TextColor, false);
d.HotKeyPrefixVisible = !((ci.Style.TextFormat & eTextFormat.HidePrefix) == eTextFormat.HidePrefix);
Rectangle mr = new Rectangle(bounds.X, bounds.Y + (bounds.Height - cell.TextMarkupBody.Bounds.Height) / 2, cell.TextMarkupBody.Bounds.Width, cell.TextMarkupBody.Bounds.Height);
mr.Offset((bounds.Width - mr.Width) / 2, 0);
cell.TextMarkupBody.Bounds = mr;
cell.TextMarkupBody.Render(d);
}
}
private static Image GetCellImage(Cell cell)
{
Image img=cell.Images.Image;
if(img==null && cell.Images.ImageIndex>=0)
img=cell.Images.GetImageByIndex(cell.Images.ImageIndex);
if(cell.IsMouseOver && (cell.Images.ImageMouseOver!=null || cell.Images.ImageMouseOverIndex>=0))
{
if(cell.Images.ImageMouseOver!=null)
img=cell.Images.ImageMouseOver;
else
img=cell.Images.GetImageByIndex(cell.Images.ImageMouseOverIndex);
}
else if(cell.Parent.Expanded && (cell.Images.ImageExpanded!=null || cell.Images.ImageExpandedIndex>=0))
{
if(cell.Images.ImageExpanded!=null)
img=cell.Images.ImageExpanded;
else
img=cell.Images.GetImageByIndex(cell.Images.ImageExpandedIndex);
}
return img;
}
public static Font GetCellFont(TreeGX tree, Cell cell)
{
Font font=tree.Font;
ElementStyle style=null;
if(cell.StyleNormal!=null)
{
style=cell.StyleNormal;
}
else
{
if(tree.NodeStyle!=null)
style=tree.NodeStyle;
else
style=new ElementStyle();
if(tree.CellStyleDefault!=null)
style=tree.CellStyleDefault;
else
style=ElementStyle.GetDefaultCellStyle(style);
}
if(style!=null && style.Font!=null)
font=style.Font;
return font;
}
}
/// <summary>
/// Represents information neccessary to paint the cell on canvas.
/// </summary>
internal class CellDisplayInfo
{
public ElementStyle Style=null;
public System.Drawing.Graphics Graphics=null;
public Cell ContextCell=null;
public Point CellOffset=Point.Empty;
public CellDisplayInfo()
{
}
public CellDisplayInfo(ElementStyle style, System.Drawing.Graphics g, Cell cell, Point cellOffset)
{
this.Style=style;
this.Graphics=g;
this.ContextCell=cell;
this.CellOffset=cellOffset;
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represents helper class for node connector display.
/// </summary>
public class ConnectorRendererEventArgs:EventArgs
{
/// <summary>
/// From node reference.
/// </summary>
public Node FromNode=null;
/// <summary>
/// From node style reference.
/// </summary>
public ElementStyle StyleFromNode=null;
/// <summary>
/// To node reference.
/// </summary>
public Node ToNode=null;
/// <summary>
/// To node style reference.
/// </summary>
public ElementStyle StyleToNode=null;
/// <summary>
/// Graphics object used for drawing.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Node offset since some node coordinates are relative.
/// </summary>
public Point Offset=Point.Empty;
/// <summary>
/// Indicates whether from node is a root node.
/// </summary>
public bool IsRootNode=false;
/// <summary>
/// Reference to node connector object that describes connector type.
/// </summary>
public NodeConnector NodeConnector=null;
/// <summary>
/// Gets or sets whether connector is link connector.
/// </summary>
public bool LinkConnector=false;
/// <summary>
/// Reference to the collection of the connector path points. Default value is null indicating there are no path points.
/// </summary>
public ConnectorPointsCollection ConnectorPoints=null;
}
}

View File

@@ -0,0 +1,141 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represents the connector display for map type.
/// </summary>
public class CurveConnectorDisplay:NodeConnectorDisplay
{
/// <summary>
/// Draws connector line between two nodes.
/// </summary>
/// <param name="info">Connector context information.</param>
public override void DrawConnector(ConnectorRendererEventArgs info)
{
if(info.NodeConnector.LineColor.IsEmpty || info.NodeConnector.LineWidth<=0)
return;
DrawCurveConnector(info);
}
private void DrawCurveConnector(ConnectorRendererEventArgs info)
{
Point pStart=this.GetStartPoint(info);
Point[] parr=this.GetEndPoint(info);
Point pEnd=parr[0];
Point pEndUnderLine=parr[1];
int lineWidth=info.NodeConnector.LineWidth;
int xMulti=1, yMulti=1;
// used for direction control
if(pStart.X>pEnd.X)
xMulti=-1;
if(pStart.Y>pEnd.Y)
yMulti=-1;
if(info.ConnectorPoints==null || info.ConnectorPoints.Count == 0)
{
// Determine whether curve can be drawn
if(Math.Abs(pStart.X-pEnd.X)<=6 || Math.Abs(pStart.Y-pEnd.Y)<=10)
{
DrawLineConnector(info,pStart,pEnd,pEndUnderLine);
}
else
{
// Create two points in between the start and end point
Point[] p=new Point[4];
p[1].X=pStart.X+(int)(Math.Abs(pStart.X-pEnd.X)*.15f*xMulti);
p[1].Y=pStart.Y+(int)(Math.Abs(pStart.Y-pEnd.Y)*.15f*yMulti);
p[2].X=pStart.X+(int)(Math.Abs(pStart.X-pEnd.X)*.5f*xMulti);
p[2].Y=pEnd.Y-(int)(yMulti*(Math.Abs(pStart.Y-pEnd.Y)*.15f));
p[0]=pStart;
p[3]=pEnd;
if(lineWidth>1)
{
GraphicsPath path=new GraphicsPath();
path.AddCurve(p,.5f);
// Check whether pStart is starting from left or right side
Rectangle fromNodeRect=info.FromNode.BoundsRelative;
fromNodeRect.Offset(info.Offset);
fromNodeRect.Inflate(-1,-1);
// if(pStart.Y>fromNodeRect.Y && pStart.Y<fromNodeRect.Bottom && pStart.X>=fromNodeRect.Right)
// {
// path.AddLine(pStart.X, pStart.Y-lineWidth*xMulti, pStart.X, pStart.Y);
// }
path.AddLine(p[0].X,p[0].Y,p[0].X+lineWidth*xMulti,p[0].Y);
if(pStart.Y>fromNodeRect.Y && pStart.Y<fromNodeRect.Bottom && pStart.X>=fromNodeRect.Right && info.IsRootNode)
{
path.AddLine(p[0].X-1,p[0].Y,p[0].X-1,p[0].Y+lineWidth*yMulti);
p[0].Y -= lineWidth*yMulti;
}
else if(pStart.Y>fromNodeRect.Y && pStart.Y<fromNodeRect.Bottom && pStart.X<=fromNodeRect.Left && info.IsRootNode)
{
path.AddLine(p[0].X+1,p[0].Y,p[0].X+1,p[0].Y+lineWidth*yMulti);
p[0].Y -= lineWidth*yMulti;
}
else
p[0].X+=(lineWidth*xMulti);
p[1].X+=(lineWidth*xMulti);
p[2].X+=(lineWidth*xMulti);
p[3].Y-=yMulti;
path.AddCurve(p,.5f);
path.AddLine(p[3].X,p[3].Y,p[3].X,p[3].Y+yMulti);
path.CloseAllFigures();
using(Brush brush=this.GetLineBrush(info))
{
info.Graphics.FillPath(brush,path);
}
}
else
{
using(Pen pen=this.GetLinePen(info))
{
info.Graphics.DrawCurve(pen,p,.5f);
}
}
}
}
else
{
ConnectorPointInfo pointInfo=GetConnectorPointInfo(info,pStart,pEnd);
if(pointInfo.Points2==null)
{
using(Pen pen=this.GetLinePen(info))
{
info.Graphics.DrawCurve(pen,pointInfo.Points1,.5f);
}
}
else
{
using(GraphicsPath path=new GraphicsPath())
{
path.AddCurve(pointInfo.Points1,.5f);
path.AddCurve(pointInfo.Points2,.5f);
path.CloseAllFigures();
using(Brush brush=this.GetLineBrush(info))
{
info.Graphics.FillPath(brush,path);
}
}
}
}
DrawEndLine(info,pStart,pEnd,pEndUnderLine);
}
}
}

View File

@@ -0,0 +1,97 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using DevComponents.Tree.Display;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represents the line connector display class.
/// </summary>
public class LineConnectorDisplay:NodeConnectorDisplay
{
/// <summary>
/// Draws connector line between two nodes.
/// </summary>
/// <param name="info">Connector context information.</param>
public override void DrawConnector(ConnectorRendererEventArgs info)
{
if(info.NodeConnector.LineColor.IsEmpty || info.NodeConnector.LineWidth<=0)
return;
DrawStarConnector(info);
}
private void DrawStarConnector(ConnectorRendererEventArgs info)
{
Point pStart=this.GetStartPoint(info);
Point[] parr=this.GetEndPoint(info);
Point pEnd=parr[0];
Point pEndUnderLine=parr[1];
if(info.ConnectorPoints==null)
{
// Determine whether curve can be drawn
if(Math.Abs(pStart.X-pEnd.X)<=6 || Math.Abs(pStart.Y-pEnd.Y)<=10)
{
DrawLineConnector(info,pStart,pEnd,pEndUnderLine);
}
else
{
Point pBottom=new Point();
Point pTop=new Point();
if(pEnd.X<pStart.X)
{
pBottom.X=pStart.X-info.NodeConnector.LineWidth;
pTop.X=pEnd.X+1;
}
else
{
pBottom.X=pStart.X+info.NodeConnector.LineWidth;
pTop.X=pEnd.X-1;
}
pBottom.Y=pStart.Y;
pTop.Y=pEnd.Y;
GraphicsPath path=new GraphicsPath();
path.AddLine(pStart,pBottom);
path.AddLine(pBottom,pEnd);
path.AddLine(pEnd,pTop);
path.AddLine(pTop,pStart);
path.CloseAllFigures();
using(Brush brush=this.GetLineBrush(info))
info.Graphics.FillPath(brush,path);
}
}
else
{
ConnectorPointInfo pointInfo=GetConnectorPointInfo(info,pStart,pEnd);
if(pointInfo.Points2==null)
{
using(Pen pen=this.GetLinePen(info))
{
info.Graphics.DrawLines(pen,pointInfo.Points1);
}
}
else
{
using(GraphicsPath path=new GraphicsPath())
{
path.AddLines(pointInfo.Points1);
path.AddLines(pointInfo.Points2);
path.CloseAllFigures();
using(Brush brush=this.GetLineBrush(info))
{
info.Graphics.FillPath(brush,path);
}
}
}
}
DrawEndLine(info,pStart,pEnd,pEndUnderLine);
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Provides information for cell rendering methods and events.
/// </summary>
public class NodeCellRendererEventArgs:NodeRendererEventArgs
{
/// <summary>
/// Gets or sets the cell being rendered.
/// </summary>
public Cell Cell=null;
/// <summary>
/// Gets or sets absolute cell bounds.
/// </summary>
public Rectangle CellBounds=Rectangle.Empty;
/// <summary>
/// Gets or sets absolute bounds for cell text.
/// </summary>
public Rectangle CellTextBounds = Rectangle.Empty;
/// <summary>
/// Gets or sets the internal cell offset.
/// </summary>
internal Point CellOffset=Point.Empty;
/// <summary>
/// Creates new instance of the class.
/// </summary>
public NodeCellRendererEventArgs():base(null,null,Rectangle.Empty,null)
{
}
/// <summary>
/// Creates new instance of the class and initializes it with default values.
/// </summary>
/// <param name="g">Reference to graphics object.</param>
/// <param name="node">Reference to context node.</param>
/// <param name="bounds">Reference to node bounds</param>
/// <param name="style">Reference to cell style</param>
/// <param name="cell">Reference to cell</param>
/// <param name="cellBounds">Reference to cell bounds</param>
public NodeCellRendererEventArgs(Graphics g, Node node, Rectangle bounds, ElementStyle style, Cell cell, Rectangle cellBounds):base(g,node,bounds,style)
{
this.Cell = cell;
this.CellBounds = cellBounds;
}
}
}

View File

@@ -0,0 +1,78 @@
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Paints node command button.
/// </summary>
internal class NodeCommandDisplay
{
public virtual void DrawCommandButton(NodeCommandPartRendererEventArgs info)
{
bool mouseOver = (info.Node.MouseOverNodePart == eMouseOverNodePart.Command);
CommandColors c=new CommandColors();
if(mouseOver)
{
c.BackColor = info.MouseOverBackColor;
c.BackColor2 = info.MouseOverBackColor2;
c.BackColorGradientAngle = info.MouseOverBackColorGradientAngle;
c.ForeColor = info.MouseOverForeColor;
}
else
{
c.BackColor = info.BackColor;
c.BackColor2 = info.BackColor2;
c.BackColorGradientAngle = info.BackColorGradientAngle;
c.ForeColor = info.ForeColor;
}
Rectangle fillBounds = info.CommandPartBounds;
fillBounds.Width--;
fillBounds.Height--;
Region oldRegion = info.Graphics.Clip.Clone() as Region;
info.Graphics.SetClip(fillBounds,CombineMode.Intersect);
if(c.BackColor2.IsEmpty)
{
if(!c.BackColor.IsEmpty)
{
using(SolidBrush brush=new SolidBrush(c.BackColor))
info.Graphics.FillRectangle(brush,fillBounds);
}
}
else
{
using(LinearGradientBrush brush=DisplayHelp.CreateLinearGradientBrush(info.CommandPartBounds, c.BackColor, c.BackColor2, c.BackColorGradientAngle))
info.Graphics.FillRectangle(brush,fillBounds);
}
if(c.ForeColor.IsEmpty) return;
int width=6;
int height=3;
GraphicsPath path=new GraphicsPath();
Point p=new Point(info.CommandPartBounds.X+(info.CommandPartBounds.Width-width)/2,info.CommandPartBounds.Y+(info.CommandPartBounds.Height-height)/2);
path.AddLine(p.X, p.Y, p.X+width,p.Y);
path.AddLine(p.X+width,p.Y,p.X+width/2,p.Y+height);
path.AddLine(p.X, p.Y,p.X+width/2,p.Y+height);
path.CloseAllFigures();
using(SolidBrush brush=new SolidBrush(c.ForeColor))
info.Graphics.FillPath(brush,path);
path.Dispose();
info.Graphics.Clip = oldRegion;
}
private class CommandColors
{
public Color BackColor=Color.Empty;
public Color BackColor2=Color.Empty;
public Color ForeColor=Color.Empty;
public int BackColorGradientAngle=0;
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Summary description for NodeCommandPartRendererEventArgs.
/// </summary>
public class NodeCommandPartRendererEventArgs:EventArgs
{
/// <summary>
/// Gets or sets reference to Graphics object, canvas node is rendered on.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Gets or sets the reference to Node object being rendered.
/// </summary>
public DevComponents.Tree.Node Node=null;
/// <summary>
/// Gets or sets command part absolute bounds.
/// </summary>
public Rectangle CommandPartBounds=Rectangle.Empty;
/// <summary>
/// Gets or sets command part back color.
/// </summary>
public Color BackColor=Color.Empty;
/// <summary>
/// Gets or sets command part end gradient color.
/// </summary>
public Color BackColor2=Color.Empty;
/// <summary>
/// Gets or sets command part text color.
/// </summary>
public Color ForeColor=Color.Empty;
/// <summary>
/// Gets or sets gradient angle.
/// </summary>
public int BackColorGradientAngle=0;
/// <summary>
/// Gets or sets command part back color when mouse is over the part.
/// </summary>
public Color MouseOverBackColor=Color.Empty;
/// <summary>
/// Gets or sets command part end gradient back color when mouse is over the part.
/// </summary>
public Color MouseOverBackColor2=Color.Empty;
/// <summary>
/// Gets or sets text color when mouse is over the part.
/// </summary>
public Color MouseOverForeColor=Color.Empty;
/// <summary>
/// Gets or sets gradient angle.
/// </summary>
public int MouseOverBackColorGradientAngle=0;
/// <summary>
/// Creates new instance of the class.
/// </summary>
/// <param name="g"></param>
public NodeCommandPartRendererEventArgs(Graphics g)
{
}
}
}

View File

@@ -0,0 +1,487 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.Tree
{
namespace Display
{
/// <summary>
/// Base class for drawing node connectors.
/// </summary>
public abstract class NodeConnectorDisplay
{
//private bool m_RootNode=false;
//private bool m_DrawRootAllLevels=false;
private bool m_EndCap=true;
//private bool m_DrawConnectorUnderNodes=true;
/// <summary>
/// Creates new instance of the object.
/// </summary>
public NodeConnectorDisplay()
{
}
/// <summary>
/// Draws connector line between two nodes.
/// </summary>
/// <param name="info">Connector context information.</param>
public virtual void DrawConnector(ConnectorRendererEventArgs info){}
/// <summary>
/// Returns the connector starting coordinates.
/// </summary>
/// <param name="info">Connector display information.</param>
/// <returns>Point object.</returns>
protected Point GetStartPoint(ConnectorRendererEventArgs info)
{
Point p=Point.Empty;
if(info.IsRootNode)
{
//int toMidPoint=info.ToNode.Bounds.Top+info.ToNode.Bounds.Height/2;
//if(info.FromNode.Bounds.Top>toMidPoint)
if(IsAbove(info.FromNode,info.ToNode))
p=new Point(info.FromNode.BoundsRelative.Left+info.FromNode.BoundsRelative.Width/2,info.FromNode.BoundsRelative.Top);
//else if(info.FromNode.Bounds.Bottom<toMidPoint)
else if(IsBelow(info.FromNode,info.ToNode))
p=new Point(info.FromNode.BoundsRelative.Left+info.FromNode.BoundsRelative.Width/2,info.FromNode.BoundsRelative.Bottom-1);
}
if(p.IsEmpty)
{
// To element to the Left
if(this.IsOnLeftSide(info.FromNode,info.ToNode))
p=new Point(info.FromNode.BoundsRelative.Left,info.FromNode.BoundsRelative.Top+info.FromNode.BoundsRelative.Height/2);
else
{
p=new Point(info.FromNode.BoundsRelative.Right,info.FromNode.BoundsRelative.Top+info.FromNode.BoundsRelative.Height/2);
if(info.IsRootNode)
p.X--;
if(!NodeDisplay.DrawExpandPart(info.FromNode) && info.FromNode.ExpandVisibility==eNodeExpandVisibility.Auto)
p.X-=(info.FromNode.BoundsRelative.Width-info.FromNode.ContentBounds.Width);
}
}
if(!p.IsEmpty)
p.Offset(info.Offset.X,info.Offset.Y);
return p;
}
/// <summary>
/// Returns true if fromNode is above the toNode.
/// </summary>
/// <param name="fromNode">From Node object.</param>
/// <param name="toNode">To Node object</param>
/// <returns>True if fromNode is above toNode.</returns>
protected bool IsAbove(Node fromNode, Node toNode)
{
//int toMidPoint=toNode.Bounds.Top+toNode.Bounds.Height/2;
//if(fromNode.Bounds.Top>toMidPoint)
if(fromNode.BoundsRelative.Top>=toNode.BoundsRelative.Bottom)
return true;
return false;
}
/// <summary>
/// Returns true if fromNode is below toNode.
/// </summary>
/// <param name="fromNode">From Node object.</param>
/// <param name="toNode">To Node object.</param>
/// <returns>True if fromNode is below toNode.</returns>
protected bool IsBelow(Node fromNode, Node toNode)
{
int toMidPoint=toNode.BoundsRelative.Top+toNode.BoundsRelative.Height/2;
if(fromNode.BoundsRelative.Bottom<toMidPoint)
return true;
return false;
}
/// <summary>
/// Returns whether connector is extended to underline the node.
/// </summary>
/// <param name="nodeStyle">Refernce to Node style.</param>
/// <returns>True if node should be underlined by connector.</returns>
protected bool UnderlineNode(ElementStyle nodeStyle)
{
if(!nodeStyle.PaintBottomBorder && !nodeStyle.PaintTopBorder &&
!nodeStyle.PaintLeftBorder && !nodeStyle.PaintRightBorder)
return true;
return false;
}
/// <summary>
/// Returns the connector end point. The array of end points. Two valid points will be returned if node needs to be underlined by connector.
/// </summary>
/// <param name="info">Connector display info.</param>
/// <returns>Array of point objects.</returns>
protected Point[] GetEndPoint(ConnectorRendererEventArgs info)
{
// If to element is to the right of the from node and has left border end point is the vertical mid-point
// If to element is to the left of the from node and has right border end point is the vertical mid-point
// If there is no border end point is text bottom
// If this is link connector the end point is the middle bottom or top point of the node
Point p=Point.Empty;
Point pLineEnd=Point.Empty;
int capWidthOffset=GetCapWidthOffset(info.NodeConnector.EndCap,info.NodeConnector.EndCapSize);
bool leftSide=this.IsOnLeftSide(info.FromNode,info.ToNode);
if(info.LinkConnector && info.FromNode.BoundsRelative.Top>info.ToNode.BoundsRelative.Bottom)
p=new Point(info.ToNode.BoundsRelative.X+info.ToNode.BoundsRelative.Width/2+(leftSide?capWidthOffset:-capWidthOffset),info.ToNode.BoundsRelative.Bottom+1);
else if(info.LinkConnector && info.FromNode.BoundsRelative.Bottom<info.ToNode.BoundsRelative.Top)
p=new Point(info.ToNode.BoundsRelative.X+info.ToNode.BoundsRelative.Width/2+(leftSide?capWidthOffset:-capWidthOffset),info.ToNode.BoundsRelative.Top-info.NodeConnector.EndCapSize.Height);
else
{
if(leftSide)
{
// To element is to the left of from node
Rectangle r=info.ToNode.BoundsRelative;
if(info.StyleToNode==null || UnderlineNode(info.StyleToNode))
{
p=new Point(r.Right,r.Bottom);
if(m_EndCap)
p.X+=capWidthOffset;
if(info.NodeConnector.UnderlineNoBorderNode)
{
Rectangle rc=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds,info.ToNode,Point.Empty);
pLineEnd=new Point(rc.Left+1,r.Bottom);
}
}
else
{
p=new Point(r.Right,r.Y+r.Height/2);
if(m_EndCap)
p.X+=capWidthOffset;
}
}
else
{
// To element to the right of from node
Rectangle r=info.ToNode.BoundsRelative;
if(info.StyleToNode==null || UnderlineNode(info.StyleToNode))
{
//r=NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds,info.ToNode.Cells[0],Point.Empty);
//r=info.ToNode.Cells[0].TextContentBounds;
p=new Point(r.X,r.Bottom);
if(m_EndCap)
p.X-=capWidthOffset;
if(info.NodeConnector.UnderlineNoBorderNode)
{
Rectangle rc=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds,info.ToNode,Point.Empty);
pLineEnd=new Point(rc.Right-1,r.Bottom);
}
}
else
{
p=new Point(r.X,r.Y+r.Height/2);
if(m_EndCap)
p.X-=capWidthOffset;
}
}
}
if(!p.IsEmpty)
p.Offset(info.Offset.X,info.Offset.Y);
if(!pLineEnd.IsEmpty)
pLineEnd.Offset(info.Offset.X,info.Offset.Y);
return new Point[] {p,pLineEnd};
}
/// <summary>
/// Returns the offest for the node connector cap.
/// </summary>
/// <param name="cap">Cap type.</param>
/// <param name="size">Cap size.</param>
/// <returns></returns>
protected int GetCapWidthOffset(eConnectorCap cap,Size size)
{
int capWidthOffset=0;
switch(cap)
{
case eConnectorCap.Arrow:
capWidthOffset=size.Width+1;
break;
case eConnectorCap.Ellipse:
capWidthOffset=size.Width;
break;
}
return capWidthOffset;
}
/// <summary>
/// Returns true if source node is on the left side of the target node.
/// </summary>
/// <param name="source">Reference to source node.</param>
/// <param name="target">Reference to target node.</param>
/// <returns>True if source is on the left side of target.</returns>
protected bool IsOnLeftSide(Node source, Node target)
{
if((source.BoundsRelative.Left+source.BoundsRelative.Width/2)>target.BoundsRelative.Left)
return true;
return false;
}
/// <summary>
/// Returns new instance of pen object for node connector line. Caller is responsible for
/// disposing of this object.
/// </summary>
/// <param name="info">Node connector display info.</param>
/// <returns>New instance of Pen object.</returns>
protected Pen GetLinePen(ConnectorRendererEventArgs info)
{
return new Pen(info.NodeConnector.LineColor,info.NodeConnector.LineWidth);
}
/// <summary>
/// Returns new instance of pen object for the end node connector line. Caller is responsible for
/// disposing of this object.
/// </summary>
/// <param name="info">Node connector display info.</param>
/// <returns>New instance of Pen object.</returns>
protected Pen GetEndLinePen(ConnectorRendererEventArgs info)
{
return new Pen(info.NodeConnector.LineColor,EndLineWidth);
}
/// <summary>
/// Returns new instance of pen object for the node underline line. Caller is responsible for
/// disposing of this object.
/// </summary>
/// <param name="info">Node connector display info.</param>
/// <returns>New instance of Pen object.</returns>
protected Pen GetEndUnderlinePen(ConnectorRendererEventArgs info)
{
return new Pen(info.NodeConnector.LineColor,EndLineWidth);
}
private int EndLineWidth
{
get {return 1;}
}
/// <summary>
/// Draws straight line connector between start and end point.
/// </summary>
/// <param name="info">Node connector display info.</param>
/// <param name="pStart">Start point.</param>
/// <param name="pEnd">End point.</param>
/// <param name="pEndUnderLine">Underline end point if any.</param>
protected void DrawLineConnector(ConnectorRendererEventArgs info,Point pStart,Point pEnd, Point pEndUnderLine)
{
if(info.NodeConnector.LineWidth>1)
{
// Merge lines nicely by filling and creating path...
int rootLineWidth=this.EndLineWidth;
int lineWidth=info.NodeConnector.LineWidth;
using(Brush brush=GetLineBrush(info))
{
GraphicsPath path=GetConnectingPath(pStart,pEnd,lineWidth,rootLineWidth,info.IsRootNode,!(IsAbove(info.FromNode,info.ToNode) || IsBelow(info.FromNode,info.ToNode)));
info.Graphics.FillPath(brush,path);
}
}
else
{
using(Pen pen=this.GetLinePen(info))
{
info.Graphics.DrawLine(pen,pStart,pEnd);
}
}
if(!pEndUnderLine.IsEmpty)
{
using(Pen pen=this.GetEndUnderlinePen(info))
{
info.Graphics.DrawLine(pen,pEnd,pEndUnderLine);
}
}
}
private GraphicsPath GetConnectingPath(Point pStart, Point pEnd, int lineStartWidth, int lineEndWidth, bool bRoot, bool bRootSide)
{
int direction=1;
if(pStart.X>pEnd.X)
direction=-1;
lineStartWidth++;
lineEndWidth++;
GraphicsPath path=new GraphicsPath();
if(bRoot && !bRootSide)
{
path.AddLine(pStart.X,pStart.Y,pStart.X+lineStartWidth*direction,pStart.Y);
// if(direction>0)
// path.AddLine(pEnd.X+lineEndWidth*direction,pEnd.Y,pEnd.X,pEnd.Y);
// else
// path.AddLine(pEnd.X,pEnd.Y,pEnd.X+lineEndWidth*direction,pEnd.Y);
if(direction>0)
{
path.AddLine(pStart.X+lineStartWidth*direction,pStart.Y, pEnd.X, pEnd.Y);
path.AddLine(pEnd.X, pEnd.Y, pEnd.X, pEnd.Y + lineEndWidth*direction);
path.AddLine(pEnd.X, pEnd.Y + lineEndWidth*direction, pStart.X, pStart.Y);
}
else
path.AddLine(pEnd.X, pEnd.Y, pEnd.X, pEnd.Y + lineEndWidth*direction);
path.CloseAllFigures();
// if(Math.Abs(pEnd.Y-pStart.Y)<=8)
// path.Widen(SystemPens.Highlight);
}
else
{
int offsetStart=lineStartWidth/2;
int offsetEnd=lineEndWidth/2;
path.AddLine(pStart.X,pStart.Y-offsetStart,pStart.X,pStart.Y+offsetStart);
path.AddLine(pEnd.X,pEnd.Y+offsetEnd,pEnd.X,pEnd.Y-offsetEnd);
path.AddLine(pEnd.X,pEnd.Y-offsetEnd,pStart.X,pStart.Y-offsetStart);
path.CloseAllFigures();
}
return path;
}
protected Brush GetLineBrush(ConnectorRendererEventArgs info)
{
return new SolidBrush(info.NodeConnector.LineColor);
}
protected void DrawEndLine(ConnectorRendererEventArgs info,Point pStart,Point pEnd,Point pEndUnderLine)
{
if(pEndUnderLine.IsEmpty)
{
switch(info.NodeConnector.EndCap)
{
case eConnectorCap.Ellipse:
{
using(Pen pen=this.GetEndLinePen(info))
{
Size endCapSize=info.NodeConnector.EndCapSize;
if(pStart.X<pEnd.X)
info.Graphics.DrawEllipse(pen,pEnd.X-1,pEnd.Y-endCapSize.Height/2,endCapSize.Width,endCapSize.Height);
else
info.Graphics.DrawEllipse(pen,pEnd.X-endCapSize.Width,pEnd.Y-endCapSize.Height/2,endCapSize.Width,endCapSize.Height);
}
break;
}
case eConnectorCap.Arrow:
{
using(Pen pen=this.GetEndLinePen(info))
{
// Connects connector line to arrow
int direction=1;
if(pStart.X>pEnd.X)
direction=-1;
info.Graphics.DrawLine(pen,pEnd,new Point(pEnd.X+info.NodeConnector.EndCapSize.Width/3*direction,pEnd.Y));
Size endCapSize=info.NodeConnector.EndCapSize;
GraphicsPath arrow=GetArrowPath(endCapSize,pStart,pEnd);
info.Graphics.DrawPath(pen,arrow);
}
break;
}
}
}
else
{
using(Pen pen=this.GetEndUnderlinePen(info))
{
info.Graphics.DrawLine(pen,pEnd,pEndUnderLine);
// Connect underline to expand part
if(NodeDisplay.DrawExpandPart(info.ToNode))
{
Rectangle re=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds,info.ToNode,info.Offset);
if (re.IsEmpty) return;
Point p2=new Point((re.X>pEndUnderLine.X?re.X:re.Right)+(re.Width/2*(re.X>pEndUnderLine.X?1:-1)),re.Bottom);
Point p1=new Point(p2.X,pEndUnderLine.Y+(pEndUnderLine.Y>p2.Y?(p2.Y-pEndUnderLine.Y)/2:-(p2.Y-pEndUnderLine.Y)/2));
info.Graphics.DrawCurve(pen,new Point[]{pEndUnderLine,p1,p2},.5f);
}
}
}
}
private GraphicsPath GetArrowPath(Size capSize,Point pStart,Point pEnd)
{
GraphicsPath path=new GraphicsPath();
int direction=1;
if(pStart.X>pEnd.X)
direction=-1;
pEnd.X+=(GetCapWidthOffset(eConnectorCap.Arrow,capSize)*direction);
path.AddLine(pEnd.X,pEnd.Y,pEnd.X-capSize.Width*direction,pEnd.Y-capSize.Height/2);
path.AddLine(pEnd.X-(2*capSize.Width/3*direction),pEnd.Y,pEnd.X-capSize.Width*direction,pEnd.Y+capSize.Height/2);
path.CloseAllFigures();
return path;
}
internal virtual ConnectorPointInfo GetConnectorPointInfo(ConnectorRendererEventArgs info, Point pStart, Point pEnd)
{
ConnectorPointInfo pointInfo=new ConnectorPointInfo();
int xMulti=1/*, yMulti=1*/;
int lineWidth=info.NodeConnector.LineWidth;
// used for direction control
if(pStart.X>pEnd.X)
xMulti=-1;
//if(pStart.Y>pEnd.Y)
// yMulti=-1;
if(info.ConnectorPoints!=null)
{
Point connPointsOffset=info.ToNode.BoundsRelative.Location;
connPointsOffset.Offset(info.Offset.X,info.Offset.Y);
GraphicsPath path=new GraphicsPath();
pointInfo.Points1=new Point[info.ConnectorPoints.Count+2];
pointInfo.Points1[0]=pStart;
pointInfo.Points1[pointInfo.Points1.Length-1]=pEnd;
if(lineWidth>1)
{
pointInfo.Points2=new Point[info.ConnectorPoints.Count+2];
pointInfo.Points2[pointInfo.Points2.Length-1]=pStart;
pointInfo.Points2[0]=pEnd;
int i=pointInfo.Points1.Length-2;
int k=1;
foreach(Point pcp in info.ConnectorPoints)
{
pointInfo.Points1[i]=pcp;
pointInfo.Points1[i].Offset(connPointsOffset.X,connPointsOffset.Y);
pointInfo.Points2[k]=new Point(pcp.X+lineWidth*xMulti,pcp.Y);
pointInfo.Points2[k].Offset(connPointsOffset.X,connPointsOffset.Y);
k++;
i--;
}
}
else
{
int i=pointInfo.Points1.Length-2;
foreach(Point pcp in info.ConnectorPoints)
{
pointInfo.Points1[i]=pcp;
pointInfo.Points1[i].Offset(connPointsOffset.X,connPointsOffset.Y);
i--;
}
}
}
return pointInfo;
}
}
}
/// <summary>
/// Represents custom connector path info.
/// </summary>
internal class ConnectorPointInfo
{
public Point[] Points1=null;
public Point[] Points2=null;
}
}

View File

@@ -0,0 +1,334 @@
using System;
using System.Drawing;
using DevComponents.Tree.Layout;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Summary description for NodeDisplay.
/// </summary>
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
/// <summary>Creates new instance of the class</summary>
/// <param name="tree">Object to initialize class with.</param>
public NodeDisplay(TreeGX tree)
{
m_Tree=tree;
}
/// <summary>
/// Paints the layout on canvas.
/// </summary>
public virtual void Paint(Graphics g, Rectangle clipRectangle)
{
}
/// <summary>
/// Gets or sets the offset of the tree content relative to the size of the container control.
/// </summary>
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;}
}
/// <summary>Gets or sets whether offset is locked, i.e. cannot be changed.</summary>
public bool LockOffset
{
get {return (!m_LockedOffset.IsEmpty);}
set
{
if(value)
m_LockedOffset=this.Offset;
else
m_LockedOffset=Point.Empty;
}
}
/// <summary>
/// Sets locked offset to specific value. Point.Empty means there is no locked offset set.
/// </summary>
/// <param name="p">New locked offset.</param>
public void SetLockedOffset(Point p)
{
m_LockedOffset=p;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public Point GetLockedOffset()
{
return m_LockedOffset;
}
/// <summary>
/// Returns the default offset for the tree content relative to the size of the container.
/// </summary>
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;
}
}
/// <summary>
/// Gets or sets the reference to the tree control managed by display class.
/// </summary>
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;
}
}
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.Tree
{
namespace Display
{
/// <summary>
/// Base class for node expand button display.
/// </summary>
public abstract class NodeExpandDisplay
{
/// <summary>Creates new instance of the class</summary>
public NodeExpandDisplay()
{
}
/// <summary>Draws expand button.</summary>
/// <param name="e">Context parameters for drawing expand button.</param>
public abstract void DrawExpandButton(NodeExpandPartRendererEventArgs e);
protected Pen GetBorderPen(NodeExpandPartRendererEventArgs e)
{
return new Pen(e.BorderColor, Dpi.Width1);
}
protected Pen GetExpandPen(NodeExpandPartRendererEventArgs e)
{
return new Pen(e.ExpandLineColor,Dpi.Width1);
}
protected Brush GetBackgroundBrush(NodeExpandPartRendererEventArgs e)
{
if(e.BackColor.IsEmpty && e.BackColor2.IsEmpty)
return null;
if(e.BackColor2.IsEmpty)
return new SolidBrush(e.BackColor);
System.Drawing.Drawing2D.LinearGradientBrush brush=DisplayHelp.CreateLinearGradientBrush(e.ExpandPartBounds,e.BackColor,e.BackColor2,e.BackColorGradientAngle);
//brush.SetSigmaBellShape(0.8f);
return brush;
}
}
}
}

View File

@@ -0,0 +1,51 @@
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represents class that paints elliptical expand button.
/// </summary>
public class NodeExpandEllipseDisplay:NodeExpandDisplay
{
/// <summary>Draws ellipse type expand button.</summary>
/// <param name="e">Expand context drawing information.</param>
public override void DrawExpandButton(NodeExpandPartRendererEventArgs e)
{
Rectangle expandPartBounds = e.ExpandPartBounds;
if (expandPartBounds.IsEmpty)
return;
Brush brush = GetBackgroundBrush(e);
expandPartBounds.Width--;
expandPartBounds.Height--;
if (brush != null)
{
e.Graphics.FillEllipse(brush, expandPartBounds);
brush.Dispose();
}
using (Pen pen = GetBorderPen(e))
{
e.Graphics.DrawEllipse(pen, expandPartBounds);
}
if (e.Node.Expanded)
{
using (Pen pen = GetExpandPen(e))
{
e.Graphics.DrawLine(pen, expandPartBounds.X + 2, expandPartBounds.Y + expandPartBounds.Height / 2, expandPartBounds.Right - 2, expandPartBounds.Y + expandPartBounds.Height / 2);
}
}
else
{
using (Pen pen = GetExpandPen(e))
{
e.Graphics.DrawLine(pen, expandPartBounds.X + 2, expandPartBounds.Y + expandPartBounds.Height / 2, expandPartBounds.Right - 2, expandPartBounds.Y + expandPartBounds.Height / 2);
e.Graphics.DrawLine(pen, expandPartBounds.X + expandPartBounds.Width / 2, expandPartBounds.Y + 2, expandPartBounds.X + expandPartBounds.Width / 2, expandPartBounds.Bottom - 2);
}
}
}
}
}

View File

@@ -0,0 +1,25 @@
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represents expand button display using predefined images.
/// </summary>
public class NodeExpandImageDisplay:NodeExpandDisplay
{
/// <summary>
/// Draws image type expand button.
/// </summary>
/// <param name="e">Expand context information</param>
public override void DrawExpandButton(NodeExpandPartRendererEventArgs e)
{
if(e.Node.Expanded)
{
if(e.ExpandImageCollapse!=null)
e.Graphics.DrawImage(e.ExpandImageCollapse,e.ExpandPartBounds);
}
else if(e.ExpandImage!=null)
e.Graphics.DrawImage(e.ExpandImage,e.ExpandPartBounds);
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using System.Drawing;
namespace DevComponents.Tree
{
/// <summary>
/// Represents event arguments for RenderExpandPart event.
/// </summary>
public class NodeExpandPartRendererEventArgs:EventArgs
{
/// <summary>
/// Gets or sets reference to Graphics object, canvas node is rendered on.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Gets or sets the reference to Node object being rendered.
/// </summary>
public DevComponents.Tree.Node Node=null;
/// <summary>Expand part bounds</summary>
public Rectangle ExpandPartBounds=Rectangle.Empty;
/// <summary>Expand part border color</summary>
public Color BorderColor=Color.Empty;
/// <summary>Expand part line color</summary>
public Color ExpandLineColor=Color.Empty;
/// <summary>Expand part background color</summary>
public Color BackColor=Color.Empty;
/// <summary>Expand part target gradient background color</summary>
public Color BackColor2=Color.Empty;
/// <summary>Gradient angle</summary>
public int BackColorGradientAngle=90;
// /// <summary>Indicates whether mouse is over the expand part</summary>
// public bool MouseOver=false;
/// <summary>Expand part image when node is expanded</summary>
public Image ExpandImage=null;
/// <summary>Expand part image when node is collapsed</summary>
public Image ExpandImageCollapse=null;
/// <summary>Internal support for expand button types</summary>
internal eExpandButtonType ExpandButtonType=eExpandButtonType.Ellipse;
/// <summary>
/// Creates new instance of the class and initializes it with default values.
/// </summary>
/// <param name="g">Reference to graphics object.</param>
public NodeExpandPartRendererEventArgs(Graphics g)
{
this.Graphics = g;
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represents class that paints rectangular expand button.
/// </summary>
public class NodeExpandRectDisplay:NodeExpandDisplay
{
/// <summary>
/// Draw rectangular type expand button.
/// </summary>
/// <param name="e">Expand button context information.</param>
public override void DrawExpandButton(NodeExpandPartRendererEventArgs e)
{
Rectangle expandPartBounds = e.ExpandPartBounds;
if (expandPartBounds.IsEmpty)
return;
expandPartBounds.Width--;
expandPartBounds.Height--;
Brush brush = GetBackgroundBrush(e);
if (brush != null)
{
e.Graphics.FillRectangle(brush, expandPartBounds);
brush.Dispose();
}
using (Pen pen = GetBorderPen(e))
{
e.Graphics.DrawRectangle(pen, expandPartBounds);
}
if (e.Node.Expanded)
{
using (Pen pen = GetExpandPen(e))
{
e.Graphics.DrawLine(pen, expandPartBounds.X + 2, expandPartBounds.Y + expandPartBounds.Height / 2, expandPartBounds.Right - 2, expandPartBounds.Y + expandPartBounds.Height / 2);
}
}
else
{
using (Pen pen = GetExpandPen(e))
{
e.Graphics.DrawLine(pen, expandPartBounds.X + 2, expandPartBounds.Y + expandPartBounds.Height / 2, expandPartBounds.Right - 2, expandPartBounds.Y + expandPartBounds.Height / 2);
e.Graphics.DrawLine(pen, expandPartBounds.X + expandPartBounds.Width / 2, expandPartBounds.Y + 2, expandPartBounds.X + expandPartBounds.Width / 2, expandPartBounds.Bottom - 2);
}
}
}
}
}

View File

@@ -0,0 +1,102 @@
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Describes colors used by Professional Renderer.
/// </summary>
public class NodeProfessionalColorTable
{
/// <summary>
/// Gets or sets the gradient begin color for top part of background.
/// </summary>
public Color NodeTopGradientBegin = ColorScheme.GetColor("B0CCF9");
/// <summary>
/// Gets or sets the middle gradient color for top part of background.
/// </summary>
public Color NodeTopGradientMiddle = ColorScheme.GetColor("E2EDFF"); // Color.FromArgb(242, 245, 250);
/// <summary>
/// Gets or sets the end gradient color for top part of background.
/// </summary>
public Color NodeTopGradientEnd = Color.Empty;
/// <summary>
/// Gets or sets the end gradient type for top part of background.
/// </summary>
public eGradientType NodeTopGradientType = eGradientType.Linear;
/// <summary>
/// Gets or sets the end gradient angle for top part of background.
/// </summary>
public int NodeTopGradientAngle = 90;
/// <summary>
/// Gets or sets the starting gradient color for bottom part of background.
/// </summary>
public Color NodeBottomGradientBegin = ColorScheme.GetColor("75ABFF");
/// <summary>
/// Gets or sets the middle gradient color for bottom part of background.
/// </summary>
public Color NodeBottomGradientMiddle = Color.FromArgb(208, 242, 248);
/// <summary>
/// Gets or sets the end gradient color for bottom part of background.
/// </summary>
public Color NodeBottomGradientEnd = Color.Empty;
/// <summary>
/// Gets or sets the type of the gradient for bottom part of background.
/// </summary>
public eGradientType NodeBottomGradientType = eGradientType.Linear;
/// <summary>
/// Gets or sets the gradient angle for bottom part of background.
/// </summary>
public int NodeBottomGradientAngle = 90;
/// <summary>
/// Gets or sets the starting gradient color for top part of background when mouse is over the node.
/// </summary>
public Color NodeMouseOverTopGradientBegin = ColorScheme.GetColor("B0CCF9");
/// <summary>
/// Gets or sets the middle gradient color for top part of background when mouse is over the node.
/// </summary>
public Color NodeMouseOverTopGradientMiddle = Color.White;
/// <summary>
/// Gets or sets the end gradient color for top part of background when mouse is over the node.
/// </summary>
public Color NodeMouseOverTopGradientEnd = Color.Empty;
/// <summary>
/// Gets or sets the gradient type for top part of background when mouse is over the node.
/// </summary>
public eGradientType NodeMouseOverTopGradientType = eGradientType.Linear;
/// <summary>
/// Gets or sets the gradient angle for top part of background when mouse is over the node.
/// </summary>
public int NodeMouseOverTopGradientAngle = 90;
/// <summary>
/// Gets or sets the starting gradient color for bottom part of background when mouse is over the node.
/// </summary>
public Color NodeMouseOverBottomGradientBegin = ColorScheme.GetColor("6599EA");
/// <summary>
/// Gets or sets the middle gradient color for bottom part of background when mouse is over the node.
/// </summary>
public Color NodeMouseOverBottomGradientMiddle = Color.Cyan;
/// <summary>
/// Gets or sets the end gradient color for bottom part of background when mouse is over the node.
/// </summary>
public Color NodeMouseOverBottomGradientEnd = Color.Empty;
/// <summary>
/// Gets or sets the gradient type for bottom part of background when mouse is over the node.
/// </summary>
public eGradientType NodeMouseOverBottomGradientType = eGradientType.Linear;
/// <summary>
/// Gets or sets the gradient angle for bottom part of background when mouse is over the node.
/// </summary>
public int NodeMouseOverBottomGradientAngle = 90;
// public Color NodeTopGradientBegin=ColorScheme.GetColor("BDCCD9");
// public Color NodeTopGradientMiddle=Color.White;
// public Color NodeTopGradientEnd=ColorScheme.GetColor("406986");
//
// public Color NodeBottomGradientBegin=ColorScheme.GetColor("03436D");
// public Color NodeBottomGradientMiddle=ColorScheme.GetColor("0BC0E9");
// public Color NodeBottomGradientEnd=ColorScheme.GetColor("0C84C1");
}
}

View File

@@ -0,0 +1,213 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represents professional rendered which provides extensive rendering above and beyond the NodeSystemRenderer.
/// </summary>
public class NodeProfessionalRenderer : NodeSystemRenderer
{
#region Private Variables
private NodeProfessionalColorTable m_ColorTable=new NodeProfessionalColorTable();
#endregion
/// <summary>
/// Gets or sets the color table used by renderer.
/// </summary>
public NodeProfessionalColorTable ColorTable
{
get { return m_ColorTable;}
set
{
m_ColorTable = value;
}
}
/// <summary>
/// Draws node background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawNodeBackground(NodeRendererEventArgs e)
{
ElementStyleDisplayInfo di=GetElementStyleDisplayInfo(e.Style,e.Graphics,DisplayHelp.GetDrawRectangle(e.NodeBounds));
PaintBackground(e);
ElementStyleDisplay.PaintBackgroundImage(di);
ElementStyleDisplay.PaintBorder(di);
// Let events occur
OnRenderNodeBackground(e);
}
private void PaintBackgroundPart(Graphics g, Rectangle bounds, GraphicsPath path, Color color1, Color color2, eGradientType gradientType, int gradientAngle)
{
if(color2.IsEmpty)
{
if(!color1.IsEmpty)
{
using(SolidBrush brush=new SolidBrush(color1))
g.FillPath(brush,path);
}
}
else if(!m_ColorTable.NodeTopGradientBegin.IsEmpty)
{
if (gradientType == eGradientType.Linear)
{
Rectangle rb = bounds;
rb.X--;
rb.Height++;
rb.Width += 2;
using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(rb, color1, color2, gradientAngle))
{
g.FillPath(brush, path);
}
}
else if (gradientType == eGradientType.Radial)
{
int d = (int)Math.Sqrt(bounds.Width * bounds.Width + bounds.Height * bounds.Height);
GraphicsPath fillPath = new GraphicsPath();
fillPath.AddEllipse(bounds.X - (d - bounds.Width), bounds.Y - (d - bounds.Height) / 2, d, d);
using (PathGradientBrush brush = new PathGradientBrush(fillPath))
{
brush.CenterColor = color1;
brush.SurroundColors = new Color[] { color2 };
g.FillPath(brush, path);
}
fillPath.Dispose();
}
}
}
/// <summary>
/// Paints background of the node.
/// </summary>
/// <param name="e">Context information.</param>
protected virtual void PaintBackground(NodeRendererEventArgs e)
{
Graphics g = e.Graphics;
bool mouseOver = e.Node.IsMouseOver;
Region oldClip = g.Clip;
Rectangle clipRect=e.NodeBounds;
clipRect.Width--;
clipRect.Height--;
g.SetClip(clipRect, CombineMode.Replace);
// Prepare colors
NodeColors colors=new NodeColors();
colors.NodeTopGradientBegin = m_ColorTable.NodeTopGradientBegin;
colors.NodeTopGradientMiddle = m_ColorTable.NodeTopGradientMiddle;
colors.NodeTopGradientEnd = m_ColorTable.NodeTopGradientEnd;
colors.NodeTopGradientType = m_ColorTable.NodeTopGradientType;
colors.NodeTopGradientAngle = m_ColorTable.NodeTopGradientAngle;
colors.NodeBottomGradientBegin = m_ColorTable.NodeBottomGradientBegin;
colors.NodeBottomGradientMiddle = m_ColorTable.NodeBottomGradientMiddle;
colors.NodeBottomGradientEnd = m_ColorTable.NodeBottomGradientEnd;
colors.NodeBottomGradientType = m_ColorTable.NodeBottomGradientType;
colors.NodeBottomGradientAngle = m_ColorTable.NodeBottomGradientAngle;
if(mouseOver)
{
colors.NodeTopGradientBegin = m_ColorTable.NodeMouseOverTopGradientBegin;
colors.NodeTopGradientMiddle = m_ColorTable.NodeMouseOverTopGradientMiddle;
colors.NodeTopGradientEnd = m_ColorTable.NodeMouseOverTopGradientEnd;
colors.NodeTopGradientType = m_ColorTable.NodeMouseOverTopGradientType;
colors.NodeTopGradientAngle = m_ColorTable.NodeMouseOverTopGradientAngle;
colors.NodeBottomGradientBegin = m_ColorTable.NodeMouseOverBottomGradientBegin;
colors.NodeBottomGradientMiddle = m_ColorTable.NodeMouseOverBottomGradientMiddle;
colors.NodeBottomGradientEnd = m_ColorTable.NodeMouseOverBottomGradientEnd;
colors.NodeBottomGradientType = m_ColorTable.NodeMouseOverBottomGradientType;
colors.NodeBottomGradientAngle = m_ColorTable.NodeMouseOverBottomGradientAngle;
}
// Paint Background, Top Part
Rectangle bounds=DisplayHelp.GetDrawRectangle(ElementStyleDisplay.GetBackgroundRectangle(e.Style,e.NodeBounds));
GraphicsPath path;
if (g.SmoothingMode == SmoothingMode.AntiAlias)
{
Rectangle r = bounds;
r.Width--;
path = ElementStyleDisplay.GetBackgroundPath(e.Style, r, eStyleBackgroundPathPart.TopHalf);
}
else
path = ElementStyleDisplay.GetBackgroundPath(e.Style, bounds, eStyleBackgroundPathPart.TopHalf);
path.CloseAllFigures();
Rectangle backRect = bounds;
backRect.Height = backRect.Height/2;
PaintBackgroundPart(g, backRect, path, colors.NodeTopGradientBegin, colors.NodeTopGradientEnd,
colors.NodeTopGradientType, colors.NodeTopGradientAngle);
Rectangle ellipse = new Rectangle(bounds.X, bounds.Y - bounds.Height / 2, bounds.Width, bounds.Height);
GraphicsPath pathFill=new GraphicsPath();
pathFill.AddEllipse(ellipse);
PathGradientBrush pathBrush = new PathGradientBrush(pathFill);
pathBrush.CenterColor = colors.NodeTopGradientMiddle;
pathBrush.SurroundColors = new Color[] { Color.Transparent };
pathBrush.CenterPoint = new PointF(ellipse.X + ellipse.Width / 2, bounds.Y);
Blend blend = new Blend();
blend.Factors = new float[] { 0f, .8f, 1f };
blend.Positions = new float[] { .0f, .8f, 1f };
pathBrush.Blend = blend;
pathFill.Dispose();
g.FillPath(pathBrush, path);
pathBrush.Dispose();
path.Dispose();
// Bottom Part
if (g.SmoothingMode == SmoothingMode.AntiAlias)
{
Rectangle r = bounds;
r.Width--;
path = ElementStyleDisplay.GetBackgroundPath(e.Style, r, eStyleBackgroundPathPart.BottomHalf);
}
else
path = ElementStyleDisplay.GetBackgroundPath(e.Style, bounds, eStyleBackgroundPathPart.BottomHalf);
path.CloseAllFigures();
backRect.Y += backRect.Height;
PaintBackgroundPart(g, backRect, path, colors.NodeBottomGradientBegin, colors.NodeBottomGradientEnd,
colors.NodeBottomGradientType, colors.NodeBottomGradientAngle);
ellipse = new Rectangle(bounds.X, bounds.Y + bounds.Height / 2 - 2, bounds.Width, bounds.Height + 4);
pathFill=new GraphicsPath();
pathFill.AddEllipse(ellipse);
pathBrush = new PathGradientBrush(pathFill);
pathBrush.CenterColor = colors.NodeBottomGradientMiddle;
pathBrush.SurroundColors = new Color[] { Color.Transparent };
pathBrush.CenterPoint = new PointF(ellipse.X + ellipse.Width / 2, bounds.Bottom);
blend = new Blend();
blend.Factors = new float[] { 0f, .5f, 1f };
blend.Positions = new float[] { .0f, .4f, 1f };
pathBrush.Blend = blend;
//path.Dispose();
g.FillPath(pathBrush, path);
pathBrush.Dispose();
pathFill.Dispose();
path.Dispose();
if (oldClip != null)
g.Clip = oldClip;
else
g.ResetClip();
}
private class NodeColors
{
public Color NodeTopGradientBegin;
public Color NodeTopGradientMiddle;
public Color NodeTopGradientEnd;
public eGradientType NodeTopGradientType=eGradientType.Linear;
public int NodeTopGradientAngle=90;
public Color NodeBottomGradientBegin;
public Color NodeBottomGradientMiddle;
public Color NodeBottomGradientEnd;
public eGradientType NodeBottomGradientType=eGradientType.Linear;
public int NodeBottomGradientAngle=90;
}
}
}

View File

@@ -0,0 +1,267 @@
using System;
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represents abstract renderer class for node objects.
/// </summary>
public abstract class NodeRenderer
{
#region Events
/// <summary>
/// Occurs when node background is being drawn.
/// </summary>
public event NodeRendererEventHandler RenderNodeBackground;
/// <summary>
/// Occurs when node expand part is being drawn.
/// </summary>
public event NodeExpandPartRendererEventHandler RenderNodeExpandPart;
/// <summary>
/// Occurs when node command part is being drawn.
/// </summary>
public event NodeCommandPartRendererEventHandler RenderNodeCommandPart;
/// <summary>
/// Occurs when cell bacgkround is being drawn.
/// </summary>
public event NodeCellRendererEventHandler RenderCellBackground;
/// <summary>
/// Occurs when cell check-box is being drawn.
/// </summary>
public event NodeCellRendererEventHandler RenderCellCheckBox;
/// <summary>
/// Occurs when cell image is being drawn.
/// </summary>
public event NodeCellRendererEventHandler RenderCellImage;
/// <summary>
/// Occurs when cell text is being drawn.
/// </summary>
public event NodeCellRendererEventHandler RenderCellText;
/// <summary>
/// Occurs when cell text is being drawn.
/// </summary>
public event SelectionRendererEventHandler RenderSelection;
/// <summary>
/// Occurs when node connector is being drawn.
/// </summary>
public event ConnectorRendererEventHandler RenderConnector;
/// <summary>
/// Occurs when tree background is rendered.
/// </summary>
public event TreeBackgroundRendererEventHandler RenderTreeBackground;
#endregion
#region Private Variables
#endregion
#region Constructor
public NodeRenderer()
{
}
#endregion
#region Internal Implementation
/// <summary>
/// Draws node background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawNodeBackground(NodeRendererEventArgs e)
{
OnRenderNodeBackground(e);
}
/// <summary>
/// Raises RenderNodeBackground event.
/// </summary>
/// <param name="e">Event arguments.</param>
protected virtual void OnRenderNodeBackground(NodeRendererEventArgs e)
{
if(RenderNodeBackground!=null)
RenderNodeBackground(this,e);
}
/// <summary>
/// Draws node expand part. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeExpandPart method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawNodeExpandPart(NodeExpandPartRendererEventArgs e)
{
OnRenderNodeExpandPart(e);
}
/// <summary>
/// Raises RenderNodeExpandPart event.
/// </summary>
/// <param name="e"></param>
protected virtual void OnRenderNodeExpandPart(NodeExpandPartRendererEventArgs e)
{
if(RenderNodeExpandPart!=null)
RenderNodeExpandPart(this,e);
}
/// <summary>
/// Draws node command part. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeCommandPart method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawNodeCommandPart(NodeCommandPartRendererEventArgs e)
{
OnRenderNodeCommandPart(e);
}
/// <summary>
/// Raises RenderNodeCommandPart event.
/// </summary>
/// <param name="e">Event arguments.</param>
protected virtual void OnRenderNodeCommandPart(NodeCommandPartRendererEventArgs e)
{
if(RenderNodeCommandPart!=null)
RenderNodeCommandPart(this,e);
}
/// <summary>
/// Draws cell background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawCellBackground(NodeCellRendererEventArgs e)
{
OnRenderCellBackground(e);
}
/// <summary>
/// Raises RenderCellBackground event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnRenderCellBackground(NodeCellRendererEventArgs e)
{
if(RenderCellBackground!=null)
RenderCellBackground(this, e);
}
/// <summary>
/// Draws cell check box. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellCheckBox method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawCellCheckBox(NodeCellRendererEventArgs e)
{
OnRenderCellCheckBox(e);
}
/// <summary>
/// Raises RenderCellCheckBox event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnRenderCellCheckBox(NodeCellRendererEventArgs e)
{
if(RenderCellCheckBox!=null)
RenderCellCheckBox(this, e);
}
/// <summary>
/// Draws cell image. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellImage method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawCellImage(NodeCellRendererEventArgs e)
{
OnRenderCellImage(e);
}
/// <summary>
/// Raises RenderCellImage event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnRenderCellImage(NodeCellRendererEventArgs e)
{
if(RenderCellImage!=null)
RenderCellImage(this, e);
}
/// <summary>
/// Draws cell text. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellText method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawCellText(NodeCellRendererEventArgs e)
{
OnRenderCellText(e);
}
/// <summary>
/// Raises RenderCellImage event.
/// </summary>
/// <param name="e">Event arguments</param>
protected virtual void OnRenderCellText(NodeCellRendererEventArgs e)
{
if(RenderCellText!=null)
RenderCellText(this, e);
}
/// <summary>
/// Draws selection for SelectedNode. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderSelection method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawSelection(SelectionRendererEventArgs e)
{
OnRenderSelection(e);
}
/// <summary>
/// Raises RenderSelection event.
/// </summary>
/// <param name="e">Event data.</param>
protected virtual void OnRenderSelection(SelectionRendererEventArgs e)
{
if(RenderSelection!=null)
RenderSelection(this, e);
}
/// <summary>
/// Draws connector between nodes. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderConnector method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawConnector(ConnectorRendererEventArgs e)
{
OnRenderConnector(e);
}
/// <summary>
/// Raises RenderConnector event.
/// </summary>
/// <param name="e">Event data.</param>
protected virtual void OnRenderConnector(ConnectorRendererEventArgs e)
{
if(RenderConnector!=null)
RenderConnector(this, e);
}
/// <summary>
/// Draws the tree background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderTreeBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public virtual void DrawTreeBackground(TreeBackgroundRendererEventArgs e)
{
OnRenderTreeBackground(e);
}
/// <summary>
/// Raises RenderTreeBackground event.
/// </summary>
/// <param name="e">Event data.</param>
protected virtual void OnRenderTreeBackground(TreeBackgroundRendererEventArgs e)
{
if(RenderTreeBackground!=null)
RenderTreeBackground(this, e);
}
#endregion
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Summary description for NodeRendererEventArgs.
/// </summary>
public class NodeRendererEventArgs:EventArgs
{
/// <summary>
/// Gets or sets reference to Graphics object, canvas node is rendered on.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Gets or sets the reference to Node object being rendered.
/// </summary>
public DevComponents.Tree.Node Node=null;
/// <summary>
/// Gets or sets the absolute node bounds.
/// </summary>
public Rectangle NodeBounds=Rectangle.Empty;
/// <summary>
/// Gets or sets the reference to element style for rendered node or cell. Style provided here is the style
/// for current node or cell state.
/// </summary>
public ElementStyle Style=null;
/// <summary>
/// Creates new instance of the class.
/// </summary>
public NodeRendererEventArgs()
{
}
public NodeRendererEventArgs(Graphics g, Node node, Rectangle bounds, ElementStyle style)
{
this.Graphics = g;
this.Node = node;
this.NodeBounds = bounds;
this.Style = style;
}
}
}

View File

@@ -0,0 +1,51 @@
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represent class that paints selection around node.
/// </summary>
internal class NodeSelectionDisplay
{
public void PaintSelection(SelectionRendererEventArgs info)
{
Rectangle inside=info.Bounds;
inside.Inflate(1,1);
inside.Width--;
inside.Height--;
Rectangle outside=info.Bounds;
outside.Inflate(info.Width,info.Width);
outside.Width--;
outside.Height--;
if(!info.BorderColor.IsEmpty)
{
using(Pen pen=new Pen(info.BorderColor,1))
{
info.Graphics.DrawRectangle(pen,inside);
info.Graphics.DrawRectangle(pen,outside);
}
}
if(!info.FillColor.IsEmpty)
{
using(SolidBrush brush=new SolidBrush(info.FillColor))
{
Region region=new Region(outside);
region.Exclude(inside);
info.Graphics.FillRegion(brush,region);
}
}
}
}
internal class NodeSelectionDisplayInfo
{
public Node Node=null;
public Graphics Graphics=null;
public Rectangle Bounds=Rectangle.Empty;
public Color BorderColor=Color.Empty;
public Color FillColor=Color.Empty;
public int Width=4;
}
}

View File

@@ -0,0 +1,215 @@
using System;
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Represents default system node and cell renderer.
/// </summary>
public class NodeSystemRenderer:NodeRenderer
{
#region Private Variables
private NodeExpandEllipseDisplay m_NodeExpandEllipseDisplay=new NodeExpandEllipseDisplay();
private NodeExpandRectDisplay m_NodeExpandRectDisplay=new NodeExpandRectDisplay();
private NodeExpandImageDisplay m_NodeExpandImageDisplay=new NodeExpandImageDisplay();
private NodeCommandDisplay m_NodeCommandDisplay=new NodeCommandDisplay();
private ElementStyleDisplayInfo m_ElementStyleDisplayInfo=new ElementStyleDisplayInfo();
private NodeSelectionDisplay m_SelectionDisplay=new NodeSelectionDisplay();
private CurveConnectorDisplay m_CurveConnectorDisplay=null;
private LineConnectorDisplay m_LineConnectorDisplay=null;
#endregion
#region Internal Implementation
/// <summary>
/// Returns ElementStyleDisplayInfo class that provides information for ElementStyle rendering.
/// </summary>
/// <param name="style">Reference to style.</param>
/// <param name="g">Reference to graphics object.</param>
/// <param name="bounds">Style bounds</param>
/// <returns>New instance of ElementStyleDisplayInfo</returns>
protected ElementStyleDisplayInfo GetElementStyleDisplayInfo(ElementStyle style, Graphics g, Rectangle bounds)
{
m_ElementStyleDisplayInfo.Style=style;
m_ElementStyleDisplayInfo.Graphics=g;
m_ElementStyleDisplayInfo.Bounds=bounds;
return m_ElementStyleDisplayInfo;
}
private NodeConnectorDisplay GetConnectorDisplay(NodeConnector c)
{
NodeConnectorDisplay d=null;
if(c==null)
return null;
switch(c.ConnectorType)
{
case eNodeConnectorType.Curve:
{
if(m_CurveConnectorDisplay==null)
m_CurveConnectorDisplay=new CurveConnectorDisplay();
d=m_CurveConnectorDisplay;
break;
}
case eNodeConnectorType.Line:
{
if(m_LineConnectorDisplay==null)
m_LineConnectorDisplay=new LineConnectorDisplay();
d=m_LineConnectorDisplay;
break;
}
}
return d;
}
/// <summary>
/// Draws node background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawNodeBackground(NodeRendererEventArgs e)
{
ElementStyleDisplayInfo di=GetElementStyleDisplayInfo(e.Style,e.Graphics,DisplayHelp.GetDrawRectangle(e.NodeBounds));
ElementStyleDisplay.Paint(di);
base.DrawNodeBackground(e);
}
/// <summary>
/// Draws node expand part. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeExpandPart method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawNodeExpandPart(NodeExpandPartRendererEventArgs e)
{
GetExpandDisplay(e.ExpandButtonType).DrawExpandButton(e);
base.DrawNodeExpandPart(e);
}
private NodeExpandDisplay GetExpandDisplay(eExpandButtonType e)
{
NodeExpandDisplay d=null;
switch(e)
{
case eExpandButtonType.Ellipse:
d=m_NodeExpandEllipseDisplay;
break;
case eExpandButtonType.Rectangle:
d=m_NodeExpandRectDisplay;
break;
case eExpandButtonType.Image:
d= m_NodeExpandImageDisplay;
break;
}
return d;
}
/// <summary>
/// Draws node command part. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderNodeCommandPart method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawNodeCommandPart(NodeCommandPartRendererEventArgs e)
{
m_NodeCommandDisplay.DrawCommandButton(e);
base.DrawNodeCommandPart(e);
}
/// <summary>
/// Draws cell background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawCellBackground(NodeCellRendererEventArgs e)
{
ElementStyleDisplayInfo di=GetElementStyleDisplayInfo(e.Style,e.Graphics,DisplayHelp.GetDrawRectangle(e.CellBounds));
ElementStyleDisplay.Paint(di);
base.DrawCellBackground(e);
}
/// <summary>
/// Draws cell check box. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellCheckBox method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawCellCheckBox(NodeCellRendererEventArgs e)
{
CellDisplay.PaintCellCheckBox(e);
base.DrawCellCheckBox(e);
}
/// <summary>
/// Draws cell image. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellImage method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawCellImage(NodeCellRendererEventArgs e)
{
CellDisplay.PaintCellImage(e);
base.DrawCellImage(e);
}
/// <summary>
/// Draws cell text. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderCellText method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawCellText(NodeCellRendererEventArgs e)
{
CellDisplay.PaintText(e);
base.DrawCellText(e);
}
/// <summary>
/// Draws selection for SelectedNode. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderSelection method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawSelection(SelectionRendererEventArgs e)
{
m_SelectionDisplay.PaintSelection(e);
base.DrawSelection(e);
}
/// <summary>
/// Draws connector between nodes. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderConnector method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawConnector(ConnectorRendererEventArgs e)
{
NodeConnectorDisplay display = GetConnectorDisplay(e.NodeConnector);
if(display!=null)
display.DrawConnector(e);
base.DrawConnector(e);
}
/// <summary>
/// Draws the tree background. If you need to provide custom rendering this is the method that you should override in your custom rendered. If you
/// do not want default rendering to occur do not call the base implementation. You can call OnRenderTreeBackground method so events can occur.
/// </summary>
/// <param name="e">Information provided for rendering.</param>
public override void DrawTreeBackground(TreeBackgroundRendererEventArgs e)
{
TreeGX tree = e.TreeGX;
Graphics g = e.Graphics;
if(!tree.BackColor.IsEmpty)
{
using(SolidBrush brush=new SolidBrush(tree.BackColor))
g.FillRectangle(brush,tree.DisplayRectangle);
}
ElementStyleDisplayInfo info=new ElementStyleDisplayInfo();
info.Bounds=tree.DisplayRectangle;
info.Graphics=g;
info.Style=tree.BackgroundStyle;
ElementStyleDisplay.Paint(info);
base.DrawTreeBackground (e);
}
#endregion
}
}

View File

@@ -0,0 +1,557 @@
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Summary description for NodeTreeDisplay.
/// </summary>
public class NodeTreeDisplay:NodeDisplay
{
#region Private Variables
// Cashed objects
ElementStyleDisplayInfo m_ElementStyleDisplayInfo=new ElementStyleDisplayInfo();
NodeCellRendererEventArgs m_CellDisplayInfo=new NodeCellRendererEventArgs();
// CurveConnectorDisplay m_CurveConnectorDisplay=null;
// LineConnectorDisplay m_LineConnectorDisplay=null;
private NodeSystemRenderer m_SystemRenderer=new NodeSystemRenderer();
private NodeProfessionalRenderer m_ProfRenderer=new NodeProfessionalRenderer();
#endregion
/// <summary>Creates new instance of the class</summary>
/// <param name="tree">Object to initialize class with.</param>
public NodeTreeDisplay(TreeGX tree):base(tree)
{
}
/// <summary>
/// Paints the treee on canvas.
/// </summary>
public override void Paint(Graphics g, Rectangle clipRectangle)
{
base.Paint(g,clipRectangle);
// Paint header
// Paint Nodes...
NodeDisplayContext context=new NodeDisplayContext();
context.Graphics=g;
context.DefaultFont=this.Tree.Font;
context.ClipRectangle=clipRectangle;
context.Offset=this.Offset;
context.Styles=this.Tree.Styles;
// Setup rendering
context.NodeRenderer = m_SystemRenderer;
if(this.Tree.NodeRenderer!=null && this.Tree.RenderMode==eNodeRenderMode.Custom)
context.NodeRenderer=this.Tree.NodeRenderer;
else if(this.Tree.RenderMode==eNodeRenderMode.Professional)
context.NodeRenderer = m_ProfRenderer;
context.NodeRendererEventArgs=new NodeRendererEventArgs();
if(this.Tree.NodeStyle!=null)
context.DefaultNodeStyle=this.Tree.NodeStyle;
else
context.DefaultNodeStyle=GetDefaultNodeStyle();
if(this.Tree.NodeStyleExpanded!=null)
context.ExpandedNodeStyle=this.Tree.NodeStyleExpanded;
if(this.Tree.NodeStyleSelected!=null)
context.SelectedNodeStyle=this.Tree.NodeStyleSelected;
if(this.Tree.NodeStyleMouseOver!=null)
context.MouseOverNodeStyle=this.Tree.NodeStyleMouseOver;
if(this.Tree.CellStyleDefault!=null)
context.CellStyleDefault=this.Tree.CellStyleDefault;
// else
// context.CellStyleDefault=ElementStyle.GetDefaultCellStyle(context.DefaultNodeStyle);
if(this.Tree.CellStyleDisabled!=null)
context.CellStyleDisabled=this.Tree.CellStyleDisabled;
else
context.CellStyleDisabled=ElementStyle.GetDefaultDisabledCellStyle();
if(this.Tree.CellStyleMouseDown!=null)
context.CellStyleMouseDown=this.Tree.CellStyleMouseDown;
if(this.Tree.CellStyleMouseOver!=null)
context.CellStyleMouseOver=this.Tree.CellStyleMouseOver;
if(this.Tree.CellStyleSelected!=null)
context.CellStyleSelected=this.Tree.CellStyleSelected;
else
context.CellStyleSelected=ElementStyle.GetDefaultSelectedCellStyle();
// Setup connector
//context.RootConnectorDisplay=GetConnectorDisplay(this.Tree.RootConnector);
//context.NodesConnectorDisplay=GetConnectorDisplay(this.Tree.NodesConnector);
//context.LinkConnectorDisplay=GetConnectorDisplay(this.Tree.LinkConnector);
context.ConnectorDisplayInfo=new ConnectorRendererEventArgs();
context.ConnectorDisplayInfo.Graphics=context.Graphics;
if(this.Tree.SelectedPathConnector!=null)
{
// Prepare nodes for path display. Downstream nodes are easily recognized when
// path upstream nodes need special treatment to improve performance
if(this.Tree.SelectedNode!=null)
{
Node n=this.Tree.SelectedNode;
while(n!=null)
{
// This marker will be reset once node is painted...
n.SelectedConnectorMarker = true;
n=n.Parent;
}
}
//context.SelectedPathConnectorDisplay=GetConnectorDisplay(this.Tree.SelectedPathConnector);
}
// Setup Node Expander Painter
context.ExpandDisplayInfo=new NodeExpandPartRendererEventArgs(context.Graphics);
context.ExpandDisplayInfo.BackColor=this.Tree.GetColor(this.Tree.ExpandBackColor, this.Tree.ExpandBackColorSchemePart);
context.ExpandDisplayInfo.BackColor2=this.Tree.GetColor(this.Tree.ExpandBackColor2, this.Tree.ExpandBackColor2SchemePart);
context.ExpandDisplayInfo.BackColorGradientAngle=this.Tree.ExpandBackColorGradientAngle;
context.ExpandDisplayInfo.BorderColor=this.Tree.GetColor(this.Tree.ExpandBorderColor, this.Tree.ExpandBorderColorSchemePart);
context.ExpandDisplayInfo.ExpandLineColor=this.Tree.GetColor(this.Tree.ExpandLineColor, this.Tree.ExpandLineColorSchemePart);
context.ExpandDisplayInfo.Graphics=context.Graphics;
context.ExpandDisplayInfo.ExpandButtonType = this.Tree.ExpandButtonType;
context.ExpandDisplayInfo.ExpandImage=this.Tree.ExpandImage;
context.ExpandDisplayInfo.ExpandImageCollapse=this.Tree.ExpandImageCollapse;
//context.ExpandDisplay=this.GetExpandDisplay(this.Tree.ExpandButtonType);
// Setup Selection Display
//context.SelectionDisplay=new NodeSelectionDisplay();
context.SelectionDisplayInfo=new SelectionRendererEventArgs();
context.SelectionDisplayInfo.Graphics=context.Graphics;
context.SelectionDisplayInfo.FillColor=this.Tree.SelectionBoxFillColor;
context.SelectionDisplayInfo.BorderColor=this.Tree.SelectionBoxBorderColor;
context.SelectionDisplayInfo.Width=this.Tree.SelectionBoxSize;
// Setup Node Command Display
//context.CommandDisplay=new NodeCommandDisplay();
context.CommandDisplayInfo=new NodeCommandPartRendererEventArgs(context.Graphics);
context.CommandDisplayInfo.BackColor=this.Tree.GetColor(this.Tree.CommandBackColor, this.Tree.CommandBackColorSchemePart);
context.CommandDisplayInfo.BackColor2=this.Tree.GetColor(this.Tree.CommandBackColor2, this.Tree.CommandBackColor2SchemePart);
context.CommandDisplayInfo.BackColorGradientAngle=this.Tree.CommandBackColorGradientAngle;
context.CommandDisplayInfo.ForeColor=this.Tree.GetColor(this.Tree.CommandForeColor, this.Tree.CommandForeColorSchemePart);
context.CommandDisplayInfo.MouseOverBackColor=this.Tree.GetColor(this.Tree.CommandMouseOverBackColor, this.Tree.CommandMouseOverBackColorSchemePart);
context.CommandDisplayInfo.MouseOverBackColor2=this.Tree.GetColor(this.Tree.CommandMouseOverBackColor2, this.Tree.CommandMouseOverBackColor2SchemePart);
context.CommandDisplayInfo.MouseOverBackColorGradientAngle=this.Tree.CommandMouseOverBackColorGradientAngle;
context.CommandDisplayInfo.MouseOverForeColor=this.Tree.GetColor(this.Tree.CommandMouseOverForeColor, this.Tree.CommandMouseOverForeColorSchemePart);
if(this.Tree.DisplayRootNode!=null)
this.PaintNode(this.Tree.DisplayRootNode, context);
else
this.PaintNodes(this.Tree.Nodes, context);
Node dragNode=this.Tree.GetDragNode();
if(dragNode!=null && dragNode.Parent==null)
{
Point p=context.Offset;
context.Offset=Point.Empty;
PaintNode(dragNode,context);
context.Offset=p;
}
PaintSelection(context);
}
private void PaintSelection(NodeDisplayContext context)
{
if(this.Tree.SelectedNode!=null && this.Tree.SelectedNode.Visible && this.Tree.SelectionBox)
{
context.SelectionDisplayInfo.Node=this.Tree.SelectedNode;
context.SelectionDisplayInfo.Bounds=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, context.SelectionDisplayInfo.Node, context.Offset);
//context.SelectionDisplay.PaintSelection(context.SelectionDisplayInfo);
context.NodeRenderer.DrawSelection(context.SelectionDisplayInfo);
}
}
private void PaintNodes(NodeCollection nodes,NodeDisplayContext context)
{
foreach(Node node in nodes)
{
PaintNode(node, context);
}
}
private void PaintNode(Node node, NodeDisplayContext context)
{
if(!node.Visible)
{
node.SelectedConnectorMarker = false;
return;
}
Rectangle r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds,node,context.Offset);
if(r.IsEmpty)
{
node.SelectedConnectorMarker = false;
return;
}
if(node.Parent!=null && !node.Parent.BoundsRelative.IsEmpty)
{
this.PaintConnector(node, context);
}
if(node.HasLinkedNodes)
{
foreach(LinkedNode linkedNode in node.LinkedNodes)
{
if(!linkedNode.Node.IsVisible)
continue;
this.PaintConnector(node,linkedNode.Node, context,true, linkedNode.ConnectorPoints);
}
}
node.SelectedConnectorMarker = false;
if(r.IntersectsWith(context.ClipRectangle) || context.ClipRectangle.IsEmpty)
PaintSingleNode(node, context);
// else if(node.HasHostedControls) // Move controls to proper location
// MoveHostedControls(node, context);
if(node.Expanded && node.Nodes.Count>0)
PaintNodes(node.Nodes,context);
}
private void PaintSingleNode(Node node, NodeDisplayContext context)
{
Rectangle r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds,node,context.Offset);
NodeRenderer renderer=context.NodeRenderer;
if(node.NodeRenderer!=null && node.RenderMode==eNodeRenderMode.Custom)
renderer = node.NodeRenderer;
// Paint node background
ElementStyle style=context.DefaultNodeStyle.Copy();
if(node.Style!=null)
style=node.Style.Copy();
bool bApllyStyles=true;
if(node.MouseOverNodePart==eMouseOverNodePart.Node && style!=null)
{
ElementStyle mouseOverStyle=context.MouseOverNodeStyle;
if(node.StyleMouseOver!=null)
mouseOverStyle=node.StyleMouseOver;
if (mouseOverStyle != null)
{
style.ApplyStyle(mouseOverStyle);
bApllyStyles = false;
}
}
// On default style apply expanded style
if(bApllyStyles && node.Expanded && style!=null)
{
ElementStyle expandedStyle=context.ExpandedNodeStyle;
if(node.StyleExpanded!=null)
expandedStyle=node.StyleExpanded;
if(expandedStyle!=null)
style.ApplyStyle(expandedStyle);
}
// Apply selected style if needed too
if(bApllyStyles && node.IsSelected && style!=null)
{
ElementStyle selectedStyle=context.SelectedNodeStyle;
if(node.StyleSelected!=null)
selectedStyle=node.StyleSelected;
if(selectedStyle!=null)
style.ApplyStyle(selectedStyle);
}
Region backRegion=null;
if(style!=null)
{
if(style.Font==null)
style.Font=context.DefaultFont;
context.NodeRendererEventArgs.Graphics=context.Graphics;
context.NodeRendererEventArgs.Node = node;
context.NodeRendererEventArgs.NodeBounds = r;
context.NodeRendererEventArgs.Style = style;
renderer.DrawNodeBackground(context.NodeRendererEventArgs);
ElementStyleDisplayInfo di=new ElementStyleDisplayInfo(style,context.Graphics,DisplayHelp.GetDrawRectangle(r));
//ElementStyleDisplay.Paint(di);
backRegion=ElementStyleDisplay.GetStyleRegion(di);
}
if(NodeDisplay.DrawExpandPart(node))
{
r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ExpandBounds,node,context.Offset);
context.ExpandDisplayInfo.Node=node;
context.ExpandDisplayInfo.ExpandPartBounds=r;
//context.ExpandDisplayInfo.MouseOver=(node.MouseOverNodePart==eMouseOverNodePart.Expand);
//context.ExpandDisplay.DrawExpandButton(context.ExpandDisplayInfo);
renderer.DrawNodeExpandPart(context.ExpandDisplayInfo);
}
// TODO: Support for display of columns should go here
// if(node.NodesColumnHeaderVisible)
// {
// foreach(ColumnHeader col in node.NodesColumns)
// {
// r=col.Bounds;
// r.Offset(context.Offset);
// r.Offset(node.Bounds.Location);
// using(Pen pen=new Pen(Color.Yellow))
// context.Graphics.DrawRectangle(pen,Display.GetDrawRectangle(r));
// }
// }
Region oldRegion=null;
if(backRegion!=null)
{
oldRegion=context.Graphics.Clip;
context.Graphics.SetClip(backRegion,CombineMode.Replace);
}
if(!node.CommandBoundsRelative.IsEmpty)
{
r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.CommandBounds,node,context.Offset);
context.CommandDisplayInfo.Node=node;
context.CommandDisplayInfo.CommandPartBounds=r;
context.CommandDisplayInfo.Graphics = context.Graphics;
//context.CommandDisplay.DrawCommandButton(context.CommandDisplayInfo);
renderer.DrawNodeCommandPart(context.CommandDisplayInfo);
context.CommandDisplayInfo.Graphics = null;
}
ElementStyle cellStyle = null;
if(context.CellStyleDefault==null)
{
cellStyle=new ElementStyle();
cellStyle.TextColor = style.TextColor;
cellStyle.TextShadowColor = style.TextShadowColor;
cellStyle.TextShadowOffset = style.TextShadowOffset;
cellStyle.TextAlignment = style.TextAlignment;
cellStyle.TextLineAlignment = style.TextLineAlignment;
cellStyle.WordWrap = style.WordWrap;
cellStyle.Font = style.Font;
}
foreach(Cell cell in node.Cells)
{
if(cell.StyleNormal!=null)
style=cell.StyleNormal;
else if(context.CellStyleDefault!=null)
style=context.CellStyleDefault.Copy();
else
style = cellStyle;
if(!cell.Enabled && cell.StyleDisabled!=null)
style.ApplyStyle(cell.StyleDisabled);
else if(!cell.Enabled && context.CellStyleDisabled!=null)
style.ApplyStyle(context.CellStyleDisabled);
else if(cell.IsMouseDown && cell.StyleMouseDown!=null)
style.ApplyStyle(cell.StyleMouseDown);
else if(cell.IsMouseDown && context.CellStyleMouseDown!=null)
style.ApplyStyle(context.CellStyleMouseDown);
else
{
if(cell.IsSelected && cell.StyleSelected!=null)
style.ApplyStyle(cell.StyleSelected);
else if(cell.IsSelected && context.CellStyleSelected!=null)
style.ApplyStyle(context.CellStyleSelected);
if(cell.IsMouseOver && cell.StyleMouseOver!=null)
style.ApplyStyle(cell.StyleMouseOver);
else if(cell.IsMouseOver && context.CellStyleMouseOver!=null)
style.ApplyStyle(context.CellStyleMouseOver);
}
r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds,node,context.Offset);
if(style!=null)
{
if(style.Font==null)
style.Font=context.DefaultFont;
Rectangle rCell=cell.BoundsRelative;
Rectangle rText=cell.TextContentBounds;
rCell.Offset(r.Location);
rText.Offset(r.Location);
ElementStyleDisplayInfo di=GetElementStyleDisplayInfo(style,context.Graphics,DisplayHelp.GetDrawRectangle(rCell));
ElementStyleDisplay.Paint(di);
NodeCellRendererEventArgs ci=GetCellDisplayInfo(style,context.Graphics,cell,r.Location, rCell, rText);
if(ci.Cell.CheckBoxVisible)
renderer.DrawCellCheckBox(ci); //CellDisplay.PaintCellCheckBox(ci);
if(!ci.Cell.Images.LargestImageSize.IsEmpty)
renderer.DrawCellImage(ci); //CellDisplay.PaintCellImage(ci);
renderer.DrawCellText(ci) ; //CellDisplay.PaintText(ci);
//CellDisplay.PaintCell(ci);
}
}
if(backRegion!=null)
context.Graphics.SetClip(oldRegion,CombineMode.Replace);
}
private void PaintConnector(Node fromNode, Node toNode, NodeDisplayContext context,bool linkConnector)
{
PaintConnector(fromNode, toNode, context, linkConnector, null);
}
private void PaintConnector(Node fromNode, Node toNode, NodeDisplayContext context,bool linkConnector, ConnectorPointsCollection connectorPoints)
{
bool isRootNode=IsRootNode(fromNode);
// if(context.RootConnectorDisplay==null && isRootNode || context.NodesConnectorDisplay==null && !isRootNode || linkConnector && context.LinkConnectorDisplay==null)
// return;
context.ConnectorDisplayInfo.FromNode=fromNode;
context.ConnectorDisplayInfo.ToNode=toNode;
context.ConnectorDisplayInfo.IsRootNode=isRootNode;
context.ConnectorDisplayInfo.LinkConnector=linkConnector;
if(fromNode.Style!=null)
context.ConnectorDisplayInfo.StyleFromNode=fromNode.Style;
else
context.ConnectorDisplayInfo.StyleFromNode=context.DefaultNodeStyle;
if(toNode.Style!=null)
context.ConnectorDisplayInfo.StyleToNode=toNode.Style;
else
context.ConnectorDisplayInfo.StyleToNode=context.DefaultNodeStyle;
context.ConnectorDisplayInfo.Offset=context.Offset;
//NodeConnectorDisplay display=null;
if(linkConnector)
{
context.ConnectorDisplayInfo.NodeConnector=this.Tree.LinkConnector;
}
else if(toNode.SelectedConnectorMarker)
{
//display = context.SelectedPathConnectorDisplay;
context.ConnectorDisplayInfo.NodeConnector=this.Tree.SelectedPathConnector;
}
else if(toNode.ParentConnector!=null)
{
//display=this.GetConnectorDisplay(toNode.ParentConnector);
context.ConnectorDisplayInfo.NodeConnector=toNode.ParentConnector;
}
else if(isRootNode)
{
//display=context.RootConnectorDisplay;
context.ConnectorDisplayInfo.NodeConnector=this.Tree.RootConnector;
}
else
{
//display=context.NodesConnectorDisplay;
context.ConnectorDisplayInfo.NodeConnector=this.Tree.NodesConnector;
}
if(linkConnector)
{
if (connectorPoints != null && connectorPoints.Count > 0)
context.ConnectorDisplayInfo.ConnectorPoints=connectorPoints;
}
else
{
if(connectorPoints!=null)
context.ConnectorDisplayInfo.ConnectorPoints=connectorPoints;
else if(toNode.ParentConnectorPoints.Count>0)
context.ConnectorDisplayInfo.ConnectorPoints=toNode.ParentConnectorPoints;
else
context.ConnectorDisplayInfo.ConnectorPoints=null;
}
context.NodeRenderer.DrawConnector(context.ConnectorDisplayInfo);
//if(display!=null)
// display.DrawConnector(context.ConnectorDisplayInfo);
}
private void PaintConnector(Node toNode, NodeDisplayContext context)
{
PaintConnector(toNode.Parent, toNode, context,false);
}
// private void MoveHostedControls(Node node, NodeDisplayContext context)
// {
// foreach(Cell cell in node.Cells)
// {
// if(cell.HostedControl!=null && cell.HostedControl.Visible)
// {
// Rectangle bounds = NodeDisplay.GetCellRectangle(eCellRectanglePart.TextBounds, cell, context.Offset);
// if(cell.HostedControl.Bounds!=bounds)
// cell.HostedControl.Bounds=bounds;
// return;
// }
// }
// }
private ElementStyleDisplayInfo GetElementStyleDisplayInfo(ElementStyle style, Graphics g, Rectangle bounds)
{
m_ElementStyleDisplayInfo.Style=style;
m_ElementStyleDisplayInfo.Graphics=g;
m_ElementStyleDisplayInfo.Bounds=bounds;
return m_ElementStyleDisplayInfo;
}
private NodeCellRendererEventArgs GetCellDisplayInfo(ElementStyle style, Graphics g, Cell cell, Point cellOffset, Rectangle cellBounds, Rectangle cellTextBounds)
{
m_CellDisplayInfo.Cell=cell;
m_CellDisplayInfo.Graphics=g;
m_CellDisplayInfo.Style=style;
m_CellDisplayInfo.CellOffset=cellOffset;
m_CellDisplayInfo.CellBounds = cellBounds;
m_CellDisplayInfo.CellTextBounds = cellTextBounds;
return m_CellDisplayInfo;
}
// private NodeConnectorDisplay GetConnectorDisplay(NodeConnector c)
// {
// NodeConnectorDisplay d=null;
// if(c==null)
// return null;
//
// switch(c.ConnectorType)
// {
// case eNodeConnectorType.Curve:
// {
// if(m_CurveConnectorDisplay==null)
// m_CurveConnectorDisplay=new CurveConnectorDisplay();
// d=m_CurveConnectorDisplay;
// break;
// }
// case eNodeConnectorType.Line:
// {
// if(m_LineConnectorDisplay==null)
// m_LineConnectorDisplay=new LineConnectorDisplay();
// d=m_LineConnectorDisplay;
// break;
// }
// }
// return d;
// }
private class NodeDisplayContext
{
public Graphics Graphics=null;
public Font DefaultFont=null;
public Rectangle ClipRectangle=Rectangle.Empty;
public Point Offset=Point.Empty;
public ElementStyle DefaultNodeStyle=null;
public ElementStyle ExpandedNodeStyle=null;
public ElementStyle SelectedNodeStyle=null;
public ElementStyle MouseOverNodeStyle=null;
public ElementStyle CellStyleDefault=null;
public ElementStyle CellStyleMouseDown=null;
public ElementStyle CellStyleMouseOver=null;
public ElementStyle CellStyleSelected=null;
public ElementStyle CellStyleDisabled=null;
public ElementStyleCollection Styles=null;
//public NodeConnectorDisplay RootConnectorDisplay=null;
//public NodeConnectorDisplay NodesConnectorDisplay=null;
//public NodeConnectorDisplay LinkConnectorDisplay=null;
//public NodeConnectorDisplay SelectedPathConnectorDisplay=null;
public ConnectorRendererEventArgs ConnectorDisplayInfo=null;
public NodeExpandPartRendererEventArgs ExpandDisplayInfo=null;
//public NodeExpandDisplay ExpandDisplay=null;
//public NodeSelectionDisplay SelectionDisplay=null;
public SelectionRendererEventArgs SelectionDisplayInfo=null;
//public NodeCommandDisplay CommandDisplay=null;
public NodeCommandPartRendererEventArgs CommandDisplayInfo=null;
public bool SelectedNodePath=false;
public NodeRenderer NodeRenderer=null;
public NodeRendererEventArgs NodeRendererEventArgs=null;
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Drawing;
namespace DevComponents.Tree
{
/// <summary>
/// Data form RenderSelection event.
/// </summary>
public class SelectionRendererEventArgs : EventArgs
{
/// <summary>
/// Gets or sets reference to Graphics object, canvas node is rendered on.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Gets or sets the reference to selected Node object.
/// </summary>
public DevComponents.Tree.Node Node=null;
/// <summary>
/// Gets or sets the selection bounds.
/// </summary>
public Rectangle Bounds=Rectangle.Empty;
/// <summary>
/// Gets or sets border color of the selection rectangle.
/// </summary>
public Color BorderColor=Color.Empty;
/// <summary>
/// Gets or sets fill color of the selection rectangle.
/// </summary>
public Color FillColor=Color.Empty;
/// <summary>
/// Gets or sets the width in pixels of the border of the selection rectangle.
/// </summary>
public int Width=4;
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Drawing;
namespace DevComponents.Tree.Display
{
/// <summary>
/// Provides data for tree background rendering events.
/// </summary>
public class TreeBackgroundRendererEventArgs
{
/// <summary>
/// Gets or sets reference to Graphics object, canvas tree background is rendered on.
/// </summary>
public System.Drawing.Graphics Graphics=null;
/// <summary>
/// Gets or sets the reference to TreeGX control.
/// </summary>
public TreeGX TreeGX = null;
/// <summary>
/// Creates new instance of the class and initializes it with default values.
/// </summary>
/// <param name="g">Reference to graphics object.</param>
public TreeBackgroundRendererEventArgs(Graphics g, TreeGX tree)
{
this.Graphics = g;
this.TreeGX = tree;
}
}
}

View File

@@ -0,0 +1,695 @@
using System.Drawing;
using System.Drawing.Drawing2D;
#if TREEGX
namespace DevComponents.Tree
#elif DOTNETBAR
namespace DevComponents.DotNetBar
#endif
{
/// <summary>
/// Summary description for Display.
/// </summary>
internal class DisplayHelp
{
private DisplayHelp()
{
}
public static LinearGradientBrush CreateLinearGradientBrush(Rectangle r,Color color1, Color color2,float gradientAngle)
{
if(r.Width<=0)
r.Width=1;
if(r.Height<=0)
r.Height=1;
return new LinearGradientBrush(new Rectangle(r.X,r.Y-1,r.Width,r.Height+1),color1,color2,gradientAngle);
}
public static LinearGradientBrush CreateLinearGradientBrush(RectangleF r,Color color1, Color color2,float gradientAngle)
{
if(r.Width<=0)
r.Width=1;
if(r.Height<=0)
r.Height=1;
return new LinearGradientBrush(new RectangleF(r.X,r.Y-1,r.Width,r.Height+1),color1,color2,gradientAngle);
}
public static LinearGradientBrush CreateLinearGradientBrush(Rectangle r,Color color1, Color color2,float gradientAngle, bool isAngleScalable)
{
if(r.Width<=0)
r.Width=1;
if(r.Height<=0)
r.Height=1;
return new LinearGradientBrush(new Rectangle(r.X,r.Y-1,r.Width,r.Height+1),color1,color2,gradientAngle,isAngleScalable);
}
public static Rectangle GetDrawRectangle(Rectangle r)
{
r.Width--;
r.Height--;
return r;
}
public static Rectangle GetPathRectangle(Rectangle r)
{
//r.Width++;
//r.Height++;
return r;
}
public static void DrawRectangle(System.Drawing.Graphics g, Color color, int x, int y, int width, int height)
{
using (Pen pen = new Pen(color, 1))
DrawRectangle(g, pen, x, y, width, height);
}
public static void DrawRectangle(System.Drawing.Graphics g, Color color, System.Drawing.Rectangle r)
{
DrawRectangle(g, color, r.X, r.Y, r.Width, r.Height);
}
public static void DrawRectangle(System.Drawing.Graphics g, System.Drawing.Pen pen, int x, int y, int width, int height)
{
// Fix for GDI issue
width--;
height--;
g.DrawRectangle(pen,x,y,width,height);
}
public static void DrawRectangle(System.Drawing.Graphics g, System.Drawing.Pen pen, System.Drawing.Rectangle r)
{
DrawRectangle(g,pen,r.X,r.Y,r.Width,r.Height);
}
public static void DrawRoundedRectangle(System.Drawing.Graphics g, Color color, Rectangle bounds, int cornerSize)
{
if (!color.IsEmpty)
{
using (Pen pen = new Pen(color))
DrawRoundedRectangle(g, pen, bounds.X, bounds.Y, bounds.Width, bounds.Height, cornerSize);
}
}
public static void DrawRoundedRectangle(System.Drawing.Graphics g, Color color, int x, int y, int width, int height, int cornerSize)
{
if (!color.IsEmpty)
{
using (Pen pen = new Pen(color))
DrawRoundedRectangle(g, pen, x, y, width, height, cornerSize);
}
}
public static void DrawRoundedRectangle(System.Drawing.Graphics g, System.Drawing.Pen pen, Rectangle bounds, int cornerSize)
{
DrawRoundedRectangle(g, pen, bounds.X, bounds.Y, bounds.Width, bounds.Height, cornerSize);
}
public static void DrawRoundedRectangle(System.Drawing.Graphics g, System.Drawing.Pen pen, int x, int y, int width, int height, int cornerSize)
{
// Fix for GDI issue
width--;
height--;
Rectangle r = new Rectangle(x, y, width, height);
SmoothingMode sm = g.SmoothingMode;
//g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
using (GraphicsPath path = GetRoundedRectanglePath(r, cornerSize))
{
g.DrawPath(pen, path);
}
g.SmoothingMode = sm;
}
public static GraphicsPath GetRoundedRectanglePath(Rectangle r, int cornerSize)
{
GraphicsPath path = new GraphicsPath();
ElementStyleDisplay.AddCornerArc(path, r, cornerSize, eCornerArc.TopLeft);
ElementStyleDisplay.AddCornerArc(path, r, cornerSize, eCornerArc.TopRight);
ElementStyleDisplay.AddCornerArc(path, r, cornerSize, eCornerArc.BottomRight);
ElementStyleDisplay.AddCornerArc(path, r, cornerSize, eCornerArc.BottomLeft);
path.CloseAllFigures();
return path;
}
public static GraphicsPath GetRoundedRectanglePath(Rectangle clientRectangle, int cornerSize, eStyleBackgroundPathPart pathPart,
eCornerType topLeftCornerType, eCornerType topRightCornerType, eCornerType bottomLeftCornerType, eCornerType bottomRightCornerType)
{
GraphicsPath path = new GraphicsPath();
if (pathPart == eStyleBackgroundPathPart.TopHalf)
clientRectangle.Height = clientRectangle.Height / 2;
else if (pathPart == eStyleBackgroundPathPart.BottomHalf)
{
int h = clientRectangle.Height;
clientRectangle.Height = clientRectangle.Height / 2;
clientRectangle.Y += (h - clientRectangle.Height - 1);
}
eCornerType corner = topLeftCornerType;
if (corner == eCornerType.Inherit)
corner = eCornerType.Square;
if (pathPart == eStyleBackgroundPathPart.BottomHalf)
corner = eCornerType.Square;
if (corner == eCornerType.Rounded)
{
ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, cornerSize, eCornerArc.TopLeft);
path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle);
}
else if (corner == eCornerType.Diagonal)
{
path.AddLine(clientRectangle.X, clientRectangle.Y + cornerSize, clientRectangle.X + cornerSize, clientRectangle.Y);
}
else
{
path.AddLine(clientRectangle.X, clientRectangle.Y + 2, clientRectangle.X, clientRectangle.Y);
path.AddLine(clientRectangle.X, clientRectangle.Y, clientRectangle.X + 2, clientRectangle.Y);
}
corner = topRightCornerType;
if (corner == eCornerType.Inherit)
corner = eCornerType.Square;
if (pathPart == eStyleBackgroundPathPart.BottomHalf)
corner = eCornerType.Square;
if (corner == eCornerType.Rounded)
{
ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, cornerSize, eCornerArc.TopRight);
path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle);
}
else if (corner == eCornerType.Diagonal)
{
path.AddLine(clientRectangle.Right - cornerSize - 1, clientRectangle.Y, clientRectangle.Right, clientRectangle.Y + cornerSize);
}
else
{
path.AddLine(clientRectangle.Right - 2, clientRectangle.Y, clientRectangle.Right, clientRectangle.Y);
path.AddLine(clientRectangle.Right, clientRectangle.Y, clientRectangle.Right, clientRectangle.Y + 2);
}
corner = bottomRightCornerType;
if (corner == eCornerType.Inherit)
corner = eCornerType.Square;
if (pathPart == eStyleBackgroundPathPart.TopHalf)
corner = eCornerType.Square;
if (corner == eCornerType.Rounded)
{
ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, cornerSize, eCornerArc.BottomRight);
path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle);
}
else if (corner == eCornerType.Diagonal)
{
path.AddLine(clientRectangle.Right, clientRectangle.Bottom - cornerSize - 1, clientRectangle.Right - cornerSize - 1, clientRectangle.Bottom);
}
else
{
path.AddLine(clientRectangle.Right, clientRectangle.Bottom - 2, clientRectangle.Right, clientRectangle.Bottom);
path.AddLine(clientRectangle.Right, clientRectangle.Bottom, clientRectangle.Right - 2, clientRectangle.Bottom);
}
corner = bottomLeftCornerType;
if (corner == eCornerType.Inherit)
corner = eCornerType.Square;
if (pathPart == eStyleBackgroundPathPart.TopHalf)
corner = eCornerType.Square;
if (corner == eCornerType.Rounded)
{
ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, cornerSize, eCornerArc.BottomLeft);
path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle);
}
else if (corner == eCornerType.Diagonal)
{
path.AddLine(clientRectangle.X + 2, clientRectangle.Bottom, clientRectangle.X, clientRectangle.Bottom - cornerSize - 1);
}
else
{
path.AddLine(clientRectangle.X + 2, clientRectangle.Bottom, clientRectangle.X, clientRectangle.Bottom);
path.AddLine(clientRectangle.X, clientRectangle.Bottom, clientRectangle.X, clientRectangle.Bottom - 2);
}
path.CloseAllFigures();
return path;
}
public static GraphicsPath GetBorderPath(Rectangle clientRectangle, int cornerSize, eStyleBackgroundPathPart pathPart,
eCornerType topLeftCornerType, eCornerType topRightCornerType, eCornerType bottomLeftCornerType, eCornerType bottomRightCornerType,
bool leftBorder, bool rightBorder, bool topBorder, bool bottomBorder)
{
GraphicsPath path = new GraphicsPath();
if (pathPart == eStyleBackgroundPathPart.TopHalf)
clientRectangle.Height = clientRectangle.Height / 2;
else if (pathPart == eStyleBackgroundPathPart.BottomHalf)
{
int h = clientRectangle.Height;
clientRectangle.Height = clientRectangle.Height / 2;
clientRectangle.Y += (h - clientRectangle.Height - 1);
}
eCornerType corner = topLeftCornerType;
if (corner == eCornerType.Inherit)
corner = eCornerType.Square;
if (pathPart == eStyleBackgroundPathPart.BottomHalf)
corner = eCornerType.Square;
if (leftBorder)
{
path.AddLine(clientRectangle.X, clientRectangle.Bottom -
(bottomBorder && (bottomLeftCornerType == eCornerType.Diagonal || bottomLeftCornerType == eCornerType.Rounded) ? cornerSize : 0),
clientRectangle.X, clientRectangle.Y +
(topBorder && (topLeftCornerType == eCornerType.Diagonal || topLeftCornerType == eCornerType.Rounded) ? cornerSize : 0));
}
if (leftBorder && topBorder)
{
if (corner == eCornerType.Rounded)
{
ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, cornerSize, eCornerArc.TopLeft);
path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle);
}
else if (corner == eCornerType.Diagonal)
{
path.AddLine(clientRectangle.X, clientRectangle.Y + cornerSize, clientRectangle.X + cornerSize, clientRectangle.Y);
}
}
if (topBorder)
{
path.AddLine(clientRectangle.X +
((topLeftCornerType == eCornerType.Diagonal || topLeftCornerType == eCornerType.Rounded) ? cornerSize : 0)
, clientRectangle.Y, clientRectangle.Right -
(rightBorder && (topRightCornerType == eCornerType.Diagonal || topRightCornerType == eCornerType.Rounded) ? cornerSize : 0),
clientRectangle.Y);
}
corner = topRightCornerType;
if (corner == eCornerType.Inherit)
corner = eCornerType.Square;
if (pathPart == eStyleBackgroundPathPart.BottomHalf)
corner = eCornerType.Square;
if (topBorder && rightBorder)
{
if (corner == eCornerType.Rounded)
{
ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, cornerSize, eCornerArc.TopRight);
path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle);
}
else if (corner == eCornerType.Diagonal)
{
path.AddLine(clientRectangle.Right - cornerSize - 1, clientRectangle.Y, clientRectangle.Right, clientRectangle.Y + cornerSize);
}
}
if (rightBorder)
{
path.AddLine(clientRectangle.Right, clientRectangle.Y +
((topRightCornerType == eCornerType.Diagonal || topRightCornerType == eCornerType.Rounded) ? cornerSize : 0),
clientRectangle.Right, clientRectangle.Bottom -
(bottomBorder && (bottomRightCornerType == eCornerType.Diagonal || bottomRightCornerType == eCornerType.Rounded) ? cornerSize : 0));
}
corner = bottomRightCornerType;
if (corner == eCornerType.Inherit)
corner = eCornerType.Square;
if (pathPart == eStyleBackgroundPathPart.TopHalf)
corner = eCornerType.Square;
if (corner == eCornerType.Rounded)
{
ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, cornerSize, eCornerArc.BottomRight);
path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle);
}
else if (corner == eCornerType.Diagonal)
{
path.AddLine(clientRectangle.Right, clientRectangle.Bottom - cornerSize - 1, clientRectangle.Right - cornerSize - 1, clientRectangle.Bottom);
}
if (bottomBorder)
{
path.AddLine(clientRectangle.Right -
((bottomRightCornerType == eCornerType.Diagonal || bottomRightCornerType == eCornerType.Rounded) ? cornerSize : 0),
clientRectangle.Bottom,
clientRectangle.X +
((bottomLeftCornerType == eCornerType.Diagonal || bottomLeftCornerType == eCornerType.Rounded) ? cornerSize : 0),
clientRectangle.Bottom);
}
corner = bottomLeftCornerType;
if (corner == eCornerType.Inherit)
corner = eCornerType.Square;
if (pathPart == eStyleBackgroundPathPart.TopHalf)
corner = eCornerType.Square;
if (corner == eCornerType.Rounded)
{
ArcData ad = ElementStyleDisplay.GetCornerArc(clientRectangle, cornerSize, eCornerArc.BottomLeft);
path.AddArc(ad.X, ad.Y, ad.Width, ad.Height, ad.StartAngle, ad.SweepAngle);
}
else if (corner == eCornerType.Diagonal)
{
path.AddLine(clientRectangle.X + 2, clientRectangle.Bottom, clientRectangle.X, clientRectangle.Bottom - cornerSize - 1);
}
return path;
}
public static void FillRoundedRectangle(Graphics g, Rectangle bounds, int cornerSize, Color color1, Color color2, int gradientAngle)
{
if (color2.IsEmpty)
{
if (!color1.IsEmpty)
{
using (SolidBrush brush = new SolidBrush(color1))
FillRoundedRectangle(g, brush, bounds, cornerSize);
}
}
else
{
using (LinearGradientBrush brush = CreateLinearGradientBrush(bounds, color1, color2, gradientAngle))
FillRoundedRectangle(g, brush, bounds, cornerSize);
}
}
public static void FillRoundedRectangle(Graphics g, Rectangle bounds, int cornerSize, Color color1, Color color2)
{
FillRoundedRectangle(g, bounds, cornerSize, color1, color2, 90);
}
public static void FillRoundedRectangle(Graphics g, Rectangle bounds, int cornerSize, Color color1)
{
using (SolidBrush brush = new SolidBrush(color1))
FillRoundedRectangle(g, brush, bounds, cornerSize);
}
public static void FillRoundedRectangle(Graphics g, Brush brush, Rectangle bounds, int cornerSize)
{
// Fix for GDI issue
bounds.Width--;
bounds.Height--;
using (GraphicsPath path = GetRoundedRectanglePath(bounds, cornerSize))
{
g.FillPath(brush, path);
}
}
public static void FillRectangle(Graphics g, Rectangle bounds, Color color1)
{
FillRectangle(g, bounds, color1, Color.Empty, 90);
}
public static void FillRectangle(Graphics g, Rectangle bounds, Color color1, Color color2)
{
FillRectangle(g, bounds, color1, color2, 90);
}
#if DOTNETBAR
public static void FillRectangle(Graphics g, Rectangle r, Rendering.LinearGradientColorTable table)
{
FillRectangle(g, r, table.Start, table.End, table.GradientAngle);
}
#endif
public static void FillRectangle(Graphics g, Rectangle r, Color color1, Color color2, int gradientAngle)
{
if (r.Width == 0 || r.Height == 0)
return;
if (color2.IsEmpty)
{
if (!color1.IsEmpty)
{
using (SolidBrush brush = new SolidBrush(color1))
g.FillRectangle(brush, r);
}
}
else
{
using (LinearGradientBrush brush = CreateLinearGradientBrush(r, color1, color2, gradientAngle))
g.FillRectangle(brush, r);
}
}
public static void FillRectangle(Graphics g, Rectangle r, Color color1, Color color2, int gradientAngle, float[] factors, float[] positions)
{
if (r.Width == 0 || r.Height == 0)
return;
if (color2.IsEmpty)
{
if (!color1.IsEmpty)
{
using (SolidBrush brush = new SolidBrush(color1))
g.FillRectangle(brush, r);
}
}
else
{
using (LinearGradientBrush brush = CreateLinearGradientBrush(r, color1, color2, gradientAngle))
{
Blend blend = new Blend(factors.Length);
blend.Factors = factors;
blend.Positions = positions;
brush.Blend = blend;
g.FillRectangle(brush, r);
}
}
}
public static void FillPath(Graphics g, GraphicsPath path, Color color1, Color color2)
{
FillPath(g, path, color1, color2, 90);
}
#if DOTNETBAR
public static void FillPath(Graphics g, GraphicsPath path, Rendering.LinearGradientColorTable table)
{
FillPath(g, path, table.Start, table.End, table.GradientAngle);
}
#endif
public static void FillPath(Graphics g, GraphicsPath path, Color color1, Color color2, int gradientAngle)
{
if (color2.IsEmpty)
{
if (!color1.IsEmpty)
{
using (SolidBrush brush = new SolidBrush(color1))
g.FillPath(brush, path);
}
}
else if(!color1.IsEmpty)
{
using (LinearGradientBrush brush = CreateLinearGradientBrush(path.GetBounds(), color1, color2, gradientAngle))
g.FillPath(brush, path);
}
}
//public static void DrawGradientLine(Graphics g, Point start, Point end, Color color1, Color color2, int gradientAngle, int penWidth)
//{
// if (color1.IsEmpty || penWidth <= 0 || start == end)
// return;
// using (GraphicsPath path = new GraphicsPath())
// {
// start.Offset(-1, -1);
// end.Offset(-1, -1);
// path.AddLine(start, end);
// using (Pen pen = new Pen(Color.White, penWidth))
// path.Widen(pen);
// Rectangle r = Rectangle.Ceiling(path.GetBounds());
// r.Inflate(1, 1);
// using (LinearGradientBrush brush = CreateLinearGradientBrush(r, color1, color2, gradientAngle))
// g.FillPath(brush, path);
// }
//}
public static void DrawLine(Graphics g, Point start, Point end, Color color, int penWidth)
{
if (!color.IsEmpty)
{
using (Pen pen = new Pen(color, penWidth))
g.DrawLine(pen, start, end);
}
}
public static void DrawLine(Graphics g, int x1, int y1, int x2, int y2, Color color, int penWidth)
{
if (!color.IsEmpty)
{
using (Pen pen = new Pen(color, penWidth))
g.DrawLine(pen, x1, y1, x2, y2);
}
}
#if DOTNETBAR
public static void DrawGradientRectangle(Graphics g, Rectangle bounds, Rendering.LinearGradientColorTable table, int penWidth)
{
DrawGradientRectangle(g, bounds, table.Start, table.End, table.GradientAngle, penWidth);
}
#endif
public static void DrawGradientRectangle(Graphics g, Rectangle bounds, Color color1, Color color2, int gradientAngle, int penWidth)
{
if (color1.IsEmpty || bounds.Width <= 0 || bounds.Height <= 0 || penWidth <= 0)
return;
Rectangle r = bounds;
// Workaround for GDI+ bug
r.Width--;
r.Height--;
using (GraphicsPath path = new GraphicsPath())
{
path.AddRectangle(r);
using (Pen pen = new Pen(color1, penWidth))
path.Widen(pen);
if (color2.IsEmpty)
{
if (!color1.IsEmpty)
{
using (SolidBrush brush = new SolidBrush(color1))
g.FillPath(brush, path);
}
}
else if (!color1.IsEmpty)
{
using (LinearGradientBrush brush = new LinearGradientBrush(bounds, color1, color2, gradientAngle))
g.FillPath(brush, path);
}
}
}
#if DOTNETBAR
public static void DrawRoundGradientRectangle(Graphics g, Rectangle bounds, Rendering.LinearGradientColorTable table, int penWidth, int roundCornerSize)
{
DrawRoundGradientRectangle(g, bounds, table.Start, table.End, table.GradientAngle, penWidth, roundCornerSize);
}
#endif
public static void DrawRoundGradientRectangle(Graphics g, Rectangle bounds, Color color1, Color color2, int gradientAngle, int penWidth, int roundCornerSize)
{
if (color1.IsEmpty && color2.IsEmpty || bounds.Width <= 0 || bounds.Height <= 0 || roundCornerSize <= 0 || penWidth <= 0)
return;
Rectangle r = bounds;
// Workaround for GDI+ bug
r.Width--;
r.Height--;
using (GraphicsPath roundPath = GetRoundedRectanglePath(r, roundCornerSize))
{
using (Pen pen = new Pen(color1, penWidth))
roundPath.Widen(pen);
if (color2.IsEmpty)
{
using (SolidBrush brush = new SolidBrush(color1))
g.FillPath(brush, roundPath);
}
else if(!color1.IsEmpty)
{
using (LinearGradientBrush brush = new LinearGradientBrush(bounds, color1, color2, gradientAngle))
g.FillPath(brush, roundPath);
}
}
}
#if DOTNETBAR
public static void DrawGradientPathBorder(Graphics g, GraphicsPath path, Rendering.LinearGradientColorTable table, int penWidth)
{
DrawGradientPathBorder(g, path, table.Start, table.End, table.GradientAngle, penWidth);
}
#endif
public static void DrawGradientPathBorder(Graphics g, GraphicsPath path, Color color1, Color color2, int gradientAngle, int penWidth)
{
using (Pen pen = new Pen(color1, penWidth))
path.Widen(pen);
Rectangle r = Rectangle.Ceiling(path.GetBounds());
r.Inflate(1, 1);
if (color2.IsEmpty)
{
if (!color1.IsEmpty)
{
using (SolidBrush brush = new SolidBrush(color1))
g.FillPath(brush, path);
}
}
else if(!color1.IsEmpty)
{
using (LinearGradientBrush brush = new LinearGradientBrush(r, color1, color2, gradientAngle))
g.FillPath(brush, path);
}
}
#if DOTNETBAR
public static void DrawGradientLine(Graphics g, Point start, Point end, Rendering.LinearGradientColorTable table, int penWidth)
{
DrawGradientLine(g, start, end, table.Start, table.End, table.GradientAngle, penWidth);
}
#endif
public static void DrawGradientLine(Graphics g, Point start, Point end, Color color1, Color color2, int gradientAngle, int penWidth)
{
if (color2.IsEmpty)
{
if (!color1.IsEmpty)
{
using (Pen pen = new Pen(color1, penWidth))
g.DrawLine(pen, start, end);
}
}
else if (!color1.IsEmpty)
{
using (GraphicsPath path = new GraphicsPath())
{
start.Offset(-1, -1);
end.Offset(-1, -1);
path.AddLine(start, end);
using (Pen pen = new Pen(color1, penWidth))
path.Widen(pen);
Rectangle r = Rectangle.Ceiling(path.GetBounds());
r.Inflate(1, 1);
using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(r, color1, color2, gradientAngle))
g.FillPath(brush, path);
}
}
}
public static void DrawGradientLine(Graphics g, Point start, Point end, Color color1, Color color2, int gradientAngle, int penWidth, float[] factors, float[] positions)
{
if (color2.IsEmpty)
{
if (!color1.IsEmpty)
{
using (Pen pen = new Pen(color1, penWidth))
g.DrawLine(pen, start, end);
}
}
else if (!color1.IsEmpty)
{
using (GraphicsPath path = new GraphicsPath())
{
start.Offset(-1, -1);
end.Offset(-1, -1);
path.AddLine(start, end);
using (Pen pen = new Pen(color1, penWidth))
path.Widen(pen);
Rectangle r = Rectangle.Ceiling(path.GetBounds());
r.Inflate(1, 1);
using (LinearGradientBrush brush = DisplayHelp.CreateLinearGradientBrush(r, color1, color2, gradientAngle))
{
Blend blend = new Blend(factors.Length);
blend.Factors = factors;
blend.Positions = positions;
brush.Blend = blend;
g.FillPath(brush, path);
}
}
}
}
}
}

View File

@@ -0,0 +1,248 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace DevComponents.Tree
{
/// <summary>
/// Provides High DPI support for DotNetBar controls.
/// </summary>
public static class Dpi
{
private static SizeF _Factor = new SizeF(1f, 1f);
private static bool _UseFactor = false;
private static bool _NormalizeScaleFactor = false;
static Dpi()
{
//Debug.WriteLine("Static constructor");
}
/// <summary>
/// Gets or sets whether scale factor when set is normalized so both Width and Height values are the same. Default value is false.
/// If using ScaleMode=font the scale factor might not be same for Width and Height so this allows opportunity to keep existing size ratios on the DotNetBar sized controls.
/// When set to true the scale factor Height will always be set to scale factor Width.
/// </summary>
public static bool NormalizeScaleFactor
{
get { return _NormalizeScaleFactor; }
set { _NormalizeScaleFactor = value; }
}
public static SizeF Factor
{
get { return _Factor; }
}
public static Size Size(Size size)
{
if (!_UseFactor) return size;
size.Width = (int)(size.Width * _Factor.Width);
size.Height = (int)(size.Height * _Factor.Height);
return size;
}
public static Rectangle Size(Rectangle r)
{
if (!_UseFactor) return r;
r.Width = (int)(r.Width * _Factor.Width);
r.Height = (int)(r.Height * _Factor.Height);
return r;
}
public static Point Size(Point p)
{
if (!_UseFactor) return p;
p.X = (int)(p.X * _Factor.Width);
p.Y = (int)(p.Y * _Factor.Height);
return p;
}
//public static DevComponents.DotNetBar.Padding Size(DevComponents.DotNetBar.Padding padding)
//{
// if (!_UseFactor) return padding;
// return new Padding((int)(padding.Left * _Factor.Width), (int)(padding.Right * _Factor.Width), (int)(padding.Top * _Factor.Height), (int)(padding.Bottom * _Factor.Height));
//}
public static int DescaleWidth(int width)
{
if (!_UseFactor) return width;
return (int)(width / _Factor.Width);
}
public static int DescaleHeight(int height)
{
if (!_UseFactor) return height;
return (int)(height / _Factor.Height);
}
internal static System.Drawing.Size Descale(System.Drawing.Size size)
{
if (!_UseFactor) return size;
size.Width = (int)(size.Width / _Factor.Width);
size.Height = (int)(size.Height / _Factor.Height);
return size;
}
public static int Width(int width)
{
if (!_UseFactor) return width;
return (int)(width * _Factor.Width);
}
public static int Height(int height)
{
if (!_UseFactor) return height;
return (int)(height * _Factor.Height);
}
public static float Height(float height)
{
if (!_UseFactor) return height;
return (height * _Factor.Height);
}
private static int _CaptionVerticalPadding = 10;
public static int CaptionVerticalPadding
{
get
{
if (!_UseFactor) return 0;
return _CaptionVerticalPadding;
}
}
public static void SetScaling(SizeF factor)
{
if (factor == _Factor) return;
if (_NormalizeScaleFactor)
factor.Height = factor.Width;
if (factor.Width == 1f && factor.Height == 1f)
{
_UseFactor = false;
_Factor = factor;
}
else
{
_UseFactor = true;
_Factor = factor;
}
UpdateStaticSizes();
}
private static void UpdateStaticSizes()
{
Width1 = Dpi.Width(1);
Width2 = Dpi.Width(2);
Width3 = Dpi.Width(3);
Width4 = Dpi.Width(4);
Width5 = Dpi.Width(5);
Width6 = Dpi.Width(6);
Width7 = Dpi.Width(7);
Width8 = Dpi.Width(8);
Width9 = Dpi.Width(9);
Width10 = Dpi.Width(10);
Width11 = Dpi.Width(11);
Width12 = Dpi.Width(12);
Width13 = Dpi.Width(13);
Width14 = Dpi.Width(14);
Width15 = Dpi.Width(15);
Width16 = Dpi.Width(16);
Width17 = Dpi.Width(17);
Width18 = Dpi.Width(18);
Width20 = Dpi.Width(20);
Width22 = Dpi.Width(22);
Width24 = Dpi.Width(24);
Width25 = Dpi.Width(25);
Width26 = Dpi.Width(26);
Width28 = Dpi.Width(28);
Width32 = Dpi.Width(32);
Width34 = Dpi.Width(34);
Height1 = Dpi.Height(1);
Height2 = Dpi.Height(2);
Height3 = Dpi.Height(3);
Height4 = Dpi.Height(4);
Height5 = Dpi.Height(5);
Height6 = Dpi.Height(6);
Height7 = Dpi.Height(7);
Height8 = Dpi.Height(8);
Height9 = Dpi.Height(9);
Height10 = Dpi.Height(10);
Height11 = Dpi.Height(11);
Height12 = Dpi.Height(12);
Height13 = Dpi.Height(13);
Height14 = Dpi.Height(14);
Height15 = Dpi.Height(15);
Height16 = Dpi.Height(16);
Height17 = Dpi.Height(17);
Height18 = Dpi.Height(18);
Height20 = Dpi.Height(20);
Height22 = Dpi.Height(22);
Height23 = Dpi.Height(23);
Height24 = Dpi.Height(24);
Height25 = Dpi.Height(25);
Height28 = Dpi.Height(28);
Height32 = Dpi.Height(32);
}
#region Static Sizes
public static int Width1 = 1;
public static int Width2 = 2;
public static int Width3 = 3;
public static int Width5 = 5;
public static int Width4 = 4;
public static int Width6 = 6;
public static int Width7 = 7;
public static int Width8 = 8;
public static int Width9 = 9;
public static int Width10 = 10;
public static int Width11 = 11;
public static int Width12 = 12;
public static int Width13 = 13;
public static int Width14 = 14;
public static int Width15 = 15;
public static int Width16 = 16;
public static int Width17 = 17;
public static int Width18 = 18;
public static int Width20 = 20;
public static int Width22 = 22;
public static int Width24 = 24;
public static int Width25 = 25;
public static int Width26 = 26;
public static int Width28 = 28;
public static int Width32 = 32;
public static int Width34 = 34;
public static int Height1 = 1;
public static int Height2 = 2;
public static int Height3 = 3;
public static int Height4 = 4;
public static int Height5 = 5;
public static int Height6 = 6;
public static int Height7 = 7;
public static int Height8 = 8;
public static int Height9 = 9;
public static int Height10 = 10;
public static int Height11 = 11;
public static int Height12 = 12;
public static int Height13 = 13;
public static int Height14 = 14;
public static int Height15 = 15;
public static int Height16 = 16;
public static int Height17 = 17;
public static int Height18 = 18;
public static int Height20 = 20;
public static int Height22 = 22;
public static int Height23 = 23;
public static int Height24 = 24;
public static int Height25 = 25;
public static int Height28 = 28;
public static int Height32 = 32;
#endregion
}
}

View File

@@ -0,0 +1,368 @@
using System;
using System.Text;
using System.Xml;
using System.Reflection;
using System.Drawing;
using System.ComponentModel;
#if DOTNETBAR
namespace DevComponents.DotNetBar
#else
namespace DevComponents.Tree
#endif
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Field)]
public class DevCoSerialize : Attribute
{
public DevCoSerialize(){}
}
/// <summary>
/// Represents class that can serialize compatible marked properties.
/// </summary>
public class ElementSerializer
{
private static string XmlImageName="image";
private static string XmlIconName="icon";
private static string XmlAttributeName="name";
// private static string XmlCollectionName="collection";
// private static string XmlTypeName="type";
// private static string XmlObjectName="object";
public static void Serialize(object element, XmlElement xmlElem)
{
PropertyInfo[] propInfo = element.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo prop in propInfo)
{
if (prop.GetCustomAttributes(typeof(DevCoSerialize), true).Length > 0)
{
// Check whether property needs to be serialized
object[] attributesDefaultValue=prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);
if (attributesDefaultValue.Length > 0)
{
DefaultValueAttribute att=attributesDefaultValue[0] as DefaultValueAttribute;
object propertyValue = prop.GetValue(element, null);
if(propertyValue==att.Value)
continue;
if(propertyValue!=null && att.Value!=null && propertyValue.Equals(att.Value))
continue;
}
else if(element.GetType().GetMethod("ShouldSerialize" + prop.Name,BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)!=null)
{
MethodInfo mi=element.GetType().GetMethod("ShouldSerialize" + prop.Name,BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
object result=mi.Invoke(element,null);
if(result is bool && !((bool)result))
continue;
}
string attributeName=XmlConvert.EncodeName(prop.Name);
Type t=prop.PropertyType;
if (t.IsPrimitive || t == typeof(string) || t.IsEnum)
{
if (t == typeof(string))
xmlElem.SetAttribute(attributeName, prop.GetValue(element, null).ToString());
else if (t.IsEnum)
{
xmlElem.SetAttribute(attributeName, Enum.Format(t, prop.GetValue(element, null), "g"));
}
else if (t == typeof(bool))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((bool)prop.GetValue(element, null)));
else if (t == typeof(Int32))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((Int32)prop.GetValue(element, null)));
else if (t == typeof(double))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((double)prop.GetValue(element, null)));
else if (t == typeof(float))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((float)prop.GetValue(element, null)));
else if (t == typeof(Int16))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((Int16)prop.GetValue(element, null)));
else if (t == typeof(Int64))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((Int64)prop.GetValue(element, null)));
else if (t == typeof(byte))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((byte)prop.GetValue(element, null)));
else if (t == typeof(char))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((char)prop.GetValue(element, null)));
else if (t == typeof(decimal))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((decimal)prop.GetValue(element, null)));
else if (t == typeof(Guid))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((Guid)prop.GetValue(element, null)));
else if (t == typeof(sbyte))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((sbyte)prop.GetValue(element, null)));
else if (t == typeof(TimeSpan))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((TimeSpan)prop.GetValue(element, null)));
else if (t == typeof(ushort))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((ushort)prop.GetValue(element, null)));
else if (t == typeof(uint))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((uint)prop.GetValue(element, null)));
else if (t == typeof(ulong))
xmlElem.SetAttribute(attributeName, XmlConvert.ToString((ulong)prop.GetValue(element, null)));
else
throw new ApplicationException("Unsupported serialization type '" + t.ToString() + "' on property '" + attributeName + "'");
}
else if (t == typeof(Color))
xmlElem.SetAttribute(attributeName, ColorToString((Color)prop.GetValue(element, null)));
else if (t == typeof(Image))
{
XmlElement imageXmlElement = xmlElem.OwnerDocument.CreateElement(XmlImageName);
imageXmlElement.SetAttribute(XmlAttributeName, attributeName);
xmlElem.AppendChild(imageXmlElement);
SerializeImage((Image)prop.GetValue(element, null), imageXmlElement);
}
else if (t == typeof(Icon))
{
XmlElement imageXmlElement = xmlElem.OwnerDocument.CreateElement(XmlIconName);
imageXmlElement.SetAttribute(XmlAttributeName, attributeName);
xmlElem.AppendChild(imageXmlElement);
SerializeIcon((Icon)prop.GetValue(element, null), imageXmlElement);
}
else if (t == typeof(Font))
{
xmlElem.SetAttribute(attributeName, FontToString((Font)prop.GetValue(element, null)));
}
else
throw new ApplicationException("Unsupported serialization type '" + t.ToString() + "'" + "' on property '" + attributeName + "'");
}
}
}
private static string ColorToString(Color clr)
{
if (clr.IsSystemColor || clr.IsNamedColor || clr.IsKnownColor)
return ("." + clr.Name);
else
return clr.ToArgb().ToString();
}
private static Color ColorFromString(string sclr)
{
if (sclr == "")
return Color.Empty;
if (sclr[0] == '.')
return Color.FromName(sclr.Substring(1));
else
return Color.FromArgb(System.Xml.XmlConvert.ToInt32(sclr));
}
private static string FontToString(Font font)
{
if (font == null)
return "";
string s = font.Name + "," + XmlConvert.ToString(font.Size) + "," + XmlConvert.ToString(font.Bold) + "," + XmlConvert.ToString(font.Italic) + "," +
XmlConvert.ToString(font.Underline) + "," + XmlConvert.ToString(font.Strikeout);
return s;
}
private static Font FontFromString(string fontString)
{
if(fontString=="")
return null;
string[] options=fontString.Split(',');
FontStyle fontStyle = FontStyle.Regular;
if (XmlConvert.ToBoolean(options[2]))
fontStyle |= FontStyle.Bold;
if (XmlConvert.ToBoolean(options[3]))
fontStyle |= FontStyle.Italic;
if (XmlConvert.ToBoolean(options[4]))
fontStyle |= FontStyle.Underline;
if (XmlConvert.ToBoolean(options[5]))
fontStyle |= FontStyle.Strikeout;
Font font = new Font(options[0], XmlConvert.ToSingle(options[1]), fontStyle);
return font;
}
public static void Deserialize(object element, XmlElement xmlElem)
{
Type type=element.GetType();
foreach(XmlAttribute att in xmlElem.Attributes)
{
string name=XmlConvert.DecodeName(att.Name);
PropertyInfo prop=type.GetProperty(name);
if(prop!=null)
{
Type t=prop.PropertyType;
if (t.IsPrimitive)
{
if(t==typeof(bool))
prop.SetValue(element, XmlConvert.ToBoolean(att.Value), null);
else if (t == typeof(Int32))
prop.SetValue(element, XmlConvert.ToInt32(att.Value), null);
else if (t == typeof(double))
prop.SetValue(element, XmlConvert.ToDouble(att.Value), null);
else if (t == typeof(float))
prop.SetValue(element, XmlConvert.ToSingle(att.Value), null);
else if (t == typeof(Int16))
prop.SetValue(element, XmlConvert.ToInt16(att.Value), null);
else if (t == typeof(Int64))
prop.SetValue(element, XmlConvert.ToInt64(att.Value), null);
else if (t == typeof(byte))
prop.SetValue(element, XmlConvert.ToByte(att.Value), null);
else if (t == typeof(char))
prop.SetValue(element, XmlConvert.ToChar(att.Value), null);
else if (t == typeof(decimal))
prop.SetValue(element, XmlConvert.ToDecimal(att.Value), null);
else if (t == typeof(Guid))
prop.SetValue(element, XmlConvert.ToGuid(att.Value), null);
else if (t == typeof(sbyte))
prop.SetValue(element, XmlConvert.ToSByte(att.Value), null);
else if (t == typeof(TimeSpan))
prop.SetValue(element, XmlConvert.ToTimeSpan(att.Value), null);
else if (t == typeof(ushort))
prop.SetValue(element, XmlConvert.ToUInt16(att.Value), null);
else if (t == typeof(uint))
prop.SetValue(element, XmlConvert.ToUInt32(att.Value), null);
else if (t == typeof(ulong))
prop.SetValue(element, XmlConvert.ToUInt64(att.Value), null);
}
else if (t == typeof(string))
prop.SetValue(element, att.Value, null);
else if (t.IsEnum)
prop.SetValue(element, Enum.Parse(t, att.Value), null);
else if (t == typeof(Color))
prop.SetValue(element, ColorFromString(att.Value), null);
else if (t == typeof(Font))
prop.SetValue(element, FontFromString(att.Value), null);
}
}
foreach(XmlElement childElem in xmlElem.ChildNodes)
{
if (childElem.Name == XmlImageName)
{
string name = XmlConvert.DecodeName(childElem.GetAttribute(XmlAttributeName));
PropertyInfo prop = type.GetProperty(name);
if (prop != null)
{
prop.SetValue(element, DeserializeImage(childElem), null);
}
}
else if (childElem.Name == XmlIconName)
{
string name = XmlConvert.DecodeName(childElem.GetAttribute(XmlAttributeName));
PropertyInfo prop = type.GetProperty(name);
if (prop != null)
{
prop.SetValue(element, DeserializeIcon(childElem), null);
}
}
}
}
public static void SerializeImage(System.Drawing.Image image,XmlElement xml)
{
if(image==null)
return;
System.IO.MemoryStream mem=new System.IO.MemoryStream(1024);
// TODO: Beta 2 issue with the ImageFormat. RawFormat on image object does not return the actual image format
// Right now it is hard coded to PNG but in final version we should get the original image format
image.Save(mem,System.Drawing.Imaging.ImageFormat.Png);
System.Text.StringBuilder sb=new System.Text.StringBuilder();
System.IO.StringWriter sw=new System.IO.StringWriter(sb);
System.Xml.XmlTextWriter xt=new System.Xml.XmlTextWriter(sw);
xt.WriteBase64(mem.GetBuffer(),0,(int)mem.Length);
xml.InnerText=sb.ToString();
}
public static void SerializeIcon(System.Drawing.Icon icon, XmlElement xml)
{
if(icon==null)
return;
System.IO.MemoryStream mem=new System.IO.MemoryStream(1024);
// TODO: Beta 2 issue with the ImageFormat. RawFormat on image object does not return the actual image format
// Right now it is hard coded to PNG but in final version we should get the original image format
icon.Save(mem);
System.Text.StringBuilder sb=new System.Text.StringBuilder();
System.IO.StringWriter sw=new System.IO.StringWriter(sb);
System.Xml.XmlTextWriter xt=new System.Xml.XmlTextWriter(sw);
xml.SetAttribute("encoding","binhex");
//xt.WriteBase64(mem.GetBuffer(),0,(int)mem.Length);
xt.WriteBinHex(mem.GetBuffer(),0,(int)mem.Length);
xml.InnerText=sb.ToString();
}
/// <summary>
/// XML element is expected to be something like <image>Image data Base64 encoded</image>
/// </summary>
/// <param name="xml">Image data</param>
/// <returns></returns>
public static System.Drawing.Image DeserializeImage(XmlElement xml)
{
System.Drawing.Image img=null;
if(xml==null || xml.InnerText=="")
return null;
System.IO.StringReader sr=new System.IO.StringReader(xml.OuterXml);
System.Xml.XmlTextReader xr= new System.Xml.XmlTextReader(sr);
System.IO.MemoryStream mem=new System.IO.MemoryStream(1024);
// Skip <image> to data
xr.Read();
byte[] base64 = new byte[1024];
int base64len = 0;
do
{
base64len = xr.ReadBase64(base64, 0, 1024);
if(base64len>0)
mem.Write(base64,0,base64len);
} while (base64len!=0);
img=System.Drawing.Image.FromStream(mem);
return img;
}
public static System.Drawing.Icon DeserializeIcon(XmlElement xml)
{
System.Drawing.Icon img=null;
if(xml==null || xml.InnerText=="")
return null;
bool bDecodeBinHex=false;
if(xml.HasAttribute("encoding") && xml.GetAttribute("encoding")=="binhex")
bDecodeBinHex=true;
System.IO.StringReader sr=new System.IO.StringReader(xml.OuterXml);
System.Xml.XmlTextReader xr= new System.Xml.XmlTextReader(sr);
System.IO.MemoryStream mem=new System.IO.MemoryStream(1024);
// Skip <image> to data
xr.Read();
byte[] base64 = new byte[1024];
int base64len = 0;
if(bDecodeBinHex)
{
do
{
base64len = xr.ReadBinHex(base64, 0, 1024);
if(base64len>0)
mem.Write(base64,0,base64len);
} while (base64len!=0);
}
else
{
do
{
base64len = xr.ReadBase64(base64, 0, 1024);
if(base64len>0)
mem.Write(base64,0,base64len);
} while (base64len!=0);
}
mem.Position=0;
img=new System.Drawing.Icon(mem);
return img;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,87 @@
using System;
using System.Text;
using System.Drawing;
using System.ComponentModel;
#if TREEGX
namespace DevComponents.Tree
#elif DOTNETBAR
namespace DevComponents.DotNetBar
#endif
{
/// <summary>
/// Defines single color blend point for the multicolor gradient fills.
/// </summary>
[ToolboxItem(false),DesignTimeVisible(false),TypeConverter(typeof(BackgroundColorBlendConverter))]
public class BackgroundColorBlend
{
#region Private Variables
private Color m_Color = Color.Empty;
private float m_Position = 0;
#endregion
#region Internal Implementation
/// <summary>
/// Creates new instance of the class. When defining multicolor gradinet blends and using the percentage positions the positions created
/// must start with 0f and end with 1f.
/// </summary>
public BackgroundColorBlend() {}
/// <summary>
/// Creates new instance of the class and initialize it with default values.
/// </summary>
public BackgroundColorBlend(Color color, float position)
{
m_Color=color;
m_Position=position;
}
/// <summary>
/// Creates new instance of the class and initialize it with default values.
/// </summary>
public BackgroundColorBlend(int color, float position)
{
m_Color = ColorScheme.GetColor(color);
m_Position = position;
}
/// <summary>
/// Gets or sets Color to use in multicolor gradient blend at specified position.
/// </summary>
[Browsable(true), Description("Indicates the Color to use in multicolor gradient blend at specified position.")]
public Color Color
{
get { return m_Color; }
set
{
m_Color = value;
OnColorBlendChanged();
}
}
private bool ShouldSerializeColor()
{
return !m_Color.IsEmpty;
}
/// <summary>
/// Gets or sets the color position in multicolor gradient blend. Values less or equal to 1 are used as percentage specifing percentages of distance along the gradient line.
/// Values greater than 1 are used as absolute pixel values of distance along the gradient line.
/// </summary>
[Browsable(true), DefaultValue(0f), Description("")]
public float Position
{
get { return m_Position; }
set
{
m_Position = value;
OnColorBlendChanged();
}
}
private void OnColorBlendChanged()
{
}
#endregion
}
}

View File

@@ -0,0 +1,244 @@
using System;
using System.Collections;
using System.Text;
using System.Drawing.Drawing2D;
using System.Drawing;
#if TREEGX
namespace DevComponents.Tree
#elif DOTNETBAR
namespace DevComponents.DotNetBar
#endif
{
/// <summary>
/// Represents Collection for the BackgroundColorBlend objects.
/// </summary>
public class BackgroundColorBlendCollection : CollectionBase
{
#region Private Variables
private ElementStyle m_Parent = null;
#endregion
#region Internal Implementation
/// <summary>Creates new instance of the class.</summary>
public BackgroundColorBlendCollection() {}
internal ElementStyle Parent
{
get { return m_Parent; }
set { m_Parent = value; }
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="item">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(BackgroundColorBlend item)
{
return List.Add(item);
}
/// <summary>
/// Adds array of new objects to the collection.
/// </summary>
/// <param name="items">Array of object to add.</param>
public void AddRange(BackgroundColorBlend[] items)
{
foreach (BackgroundColorBlend item in items)
this.Add(item);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public BackgroundColorBlend this[int index]
{
get {return (BackgroundColorBlend)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, BackgroundColorBlend value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(BackgroundColorBlend value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(BackgroundColorBlend value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(BackgroundColorBlend value)
{
List.Remove(value);
}
//protected override void OnRemoveComplete(int index,object value)
//{
// base.OnRemoveComplete(index,value);
// BackgroundColorBlend me=value as BackgroundColorBlend;
//}
//protected override void OnInsertComplete(int index,object value)
//{
// base.OnInsertComplete(index,value);
// BackgroundColorBlend me=value as BackgroundColorBlend;
//}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(BackgroundColorBlend[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the BackgroundColorBlend array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(BackgroundColorBlend[] array)
{
List.CopyTo(array,0);
}
/// <summary>
/// Creates ColorBlend object based on the members of the collection. ColorBlend object will be valid only if all members of the collection
/// represents relative/percentage based color blends.
/// </summary>
/// <returns></returns>
public ColorBlend GetColorBlend()
{
ColorBlend blend = new ColorBlend();
Color[] colors = new Color[this.Count];
float[] positions = new float[this.Count];
for(int i=0; i<this.Count; i++)
{
BackgroundColorBlend b = this[i];
colors[i] = b.Color;
positions[i] = b.Position;
}
blend.Colors = colors;
blend.Positions = positions;
return blend;
}
/// <summary>
/// Adds the BackgroundColorBlend objects from the collection.
/// </summary>
/// <param name="col">Collection to copy objects from</param>
public void CopyFrom(BackgroundColorBlendCollection col)
{
foreach (BackgroundColorBlend b in col)
this.Add(b);
}
internal eBackgroundColorBlendType GetBlendType()
{
BackgroundColorBlendCollection c = this;
if (c.Count <= 1)
return eBackgroundColorBlendType.Invalid;
eBackgroundColorBlendType t = eBackgroundColorBlendType.Invalid;
foreach (BackgroundColorBlend b in c)
{
if (b.Position == 0 || b.Position == 1f)
continue;
if (b.Position <= 1f)
{
if (t == eBackgroundColorBlendType.Invalid)
t = eBackgroundColorBlendType.Relative;
else if (t == eBackgroundColorBlendType.Absolute)
{
t = eBackgroundColorBlendType.Invalid;
break;
}
}
else
{
if (t == eBackgroundColorBlendType.Invalid)
t = eBackgroundColorBlendType.Absolute;
else if (t == eBackgroundColorBlendType.Relative)
{
t = eBackgroundColorBlendType.Invalid;
break;
}
}
}
if (c.Count == 2 && c[0].Position == 0f && c[1].Position == 1f)
return eBackgroundColorBlendType.Relative;
if (t == eBackgroundColorBlendType.Invalid)
return t;
if (t == eBackgroundColorBlendType.Relative && c[0].Position != 0f && c[c.Count - 1].Position != 1f)
return eBackgroundColorBlendType.Invalid;
else if (t == eBackgroundColorBlendType.Absolute && ((c.Count / 2) * 2 != c.Count))
return eBackgroundColorBlendType.Invalid;
return t;
}
/// <summary>
/// Initializes the collection with the two color blend.
/// </summary>
/// <param name="collection">Collection to initialize.</param>
/// <param name="backColor1">Start color.</param>
/// <param name="backColor2">End color.</param>
public static void InitializeCollection(BackgroundColorBlendCollection collection, int backColor1, int backColor2)
{
InitializeCollection(collection, ColorScheme.GetColor(backColor1), ColorScheme.GetColor(backColor2));
}
/// <summary>
/// Initializes the collection with the two color blend.
/// </summary>
/// <param name="collection">Collection to initialize.</param>
/// <param name="backColor1">Start color.</param>
/// <param name="backColor2">End color.</param>
public static void InitializeCollection(BackgroundColorBlendCollection collection, Color backColor1, Color backColor2)
{
collection.Clear();
collection.Add(new BackgroundColorBlend(backColor1, 0f));
collection.Add(new BackgroundColorBlend(backColor2, 1f));
}
#endregion
}
internal enum eBackgroundColorBlendType
{
Invalid,
Relative,
Absolute
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Reflection;
using System.Drawing;
#if TREEGX
namespace DevComponents.Tree
#elif DOTNETBAR
namespace DevComponents.DotNetBar
#endif
{
/// <summary>
/// Represents BackgroundColorBlend object converter.
/// </summary>
public class BackgroundColorBlendConverter : TypeConverter
{
public BackgroundColorBlendConverter() { }
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if(destinationType==typeof(InstanceDescriptor))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if(destinationType==null)
throw new ArgumentNullException("destinationType");
if((destinationType==typeof(InstanceDescriptor)) && (value is BackgroundColorBlend))
{
BackgroundColorBlend doc = (BackgroundColorBlend)value;
Type[] constructorParams = null;
MemberInfo constructorMemberInfo = null;
object[] constructorValues = null;
constructorParams = new Type[2] { typeof(Color), typeof(float) };
constructorMemberInfo = typeof(BackgroundColorBlend).GetConstructor(constructorParams);
constructorValues = new object[2] { doc.Color, doc.Position };
if (constructorMemberInfo != null)
{
return new InstanceDescriptor(constructorMemberInfo, constructorValues);
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Text;
#if TREEGX
namespace DevComponents.Tree
#elif DOTNETBAR
namespace DevComponents.DotNetBar
#endif
{
/// <summary>
/// Defines the provider for the element style classes support.
/// </summary>
public interface IElementStyleClassProvider
{
/// <summary>
/// Returns the instance of the ElementStyle with given class name or null if there is no class with that name defined.
/// </summary>
/// <param name="className">Class name. See static members of ElementStyleClassKeys class for the list of available keys.</param>
/// <returns>Instance of ElementStyle for given class name or null if class cannot be found.</returns>
ElementStyle GetClass(string className);
}
}

View File

@@ -0,0 +1,168 @@
using System;
using System.Collections;
namespace DevComponents.Tree
{
/// <summary>
/// Represents collection for Node objects.
/// </summary>
public class ElementStyleCollection:CollectionBase
{
#region Private Variables
private TreeGX m_TreeControl=null;
//private Hashtable m_InnerHashtable=new Hashtable();
#endregion
#region Internal Implementation
/// <summary>Creates new instance of the object.</summary>
public ElementStyleCollection()
{
}
internal TreeGX TreeControl
{
get {return m_TreeControl;}
set {m_TreeControl=value;}
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="tab">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(ElementStyle style)
{
return List.Add(style);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public ElementStyle this[int index]
{
get {return (ElementStyle)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Returns reference to the object in collection based on it's name.
/// </summary>
public ElementStyle this[string name]
{
get
{
foreach(ElementStyle style in this.List)
{
if(style.Name==name)
return style;
}
return null;
}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, ElementStyle value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(ElementStyle value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(ElementStyle value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(ElementStyle value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
ElementStyle style=value as ElementStyle;
style.Parent=null;
//m_InnerHashtable.Remove(style.Name);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
ElementStyle style=value as ElementStyle;
if(style.Parent!=null && style.Parent!=this)
style.Parent.Remove(style);
style.Parent=this;
//m_InnerHashtable.Add(style.Name,style);
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(ElementStyle[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the Node array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(ElementStyle[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
base.OnClear();
}
#endregion
}
#region ElementStyleCollectionEditor
/// <summary>
/// Support for ElementStyle design-time editor.
/// </summary>
public class ElementStyleCollectionEditor:System.ComponentModel.Design.CollectionEditor
{
/// <summary>Creates new instance of the object.</summary>
public ElementStyleCollectionEditor(Type type):base(type)
{
}
protected override Type CreateCollectionItemType()
{
return typeof(ElementStyle);
}
protected override Type[] CreateNewItemTypes()
{
return new Type[] {typeof(ElementStyle)};
}
protected override object CreateInstance(Type itemType)
{
object item=base.CreateInstance(itemType);
return item;
}
}
#endregion
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,213 @@
using System;
using System.Drawing;
using System.Collections;
#if TREEGX
namespace DevComponents.Tree
#elif DOTNETBAR
namespace DevComponents.DotNetBar
#endif
{
/// <summary>
/// Represents the layout for the element style.
/// </summary>
internal class ElementStyleLayout
{
public ElementStyleLayout()
{
}
/// <summary>
/// Calculates size of an style element.
/// </summary>
/// <param name="style">Style to calculate size for.</param>
/// <param name="defaultFont">Default font that will be used by style if style does not uses it's own font.</param>
/// <returns>Size of the style element. At this time only Height memeber will be calculated.</returns>
public static void CalculateStyleSize(ElementStyle style, Font defaultFont)
{
int height=defaultFont.Height;
ElementStyle s = ElementStyleDisplay.GetElementStyle(style);
if(s.Font!=null)
height=s.Font.Height;
if(s.PaintTopBorder)
{
height+=s.BorderTopWidth;
}
if(s.PaintBottomBorder)
{
height+=s.BorderBottomWidth;
}
height+=(s.MarginTop+style.MarginBottom);
height+=(s.PaddingTop+s.PaddingBottom);
style.SetSize(new Size(0,height));
}
/// <summary>
/// Returns the total white space for a style. Whitespace is the space between the edge of the element and inner content of the element.
/// </summary>
/// <param name="es">Style to return white space for</param>
/// <returns></returns>
public static int HorizontalStyleWhiteSpace(ElementStyle es)
{
return LeftWhiteSpace(es)+RightWhiteSpace(es);
}
/// <summary>
/// Returns the total white space for a style. Whitespace is the space between the edge of the element and inner content of the element.
/// </summary>
/// <param name="es">Style to return white space for.</param>
/// <returns></returns>
public static int VerticalStyleWhiteSpace(ElementStyle es)
{
return TopWhiteSpace(es)+BottomWhiteSpace(es);
}
/// <summary>
/// Returns total white space for left side of the style. Whitespace is the space between the edge of the element and inner content of the element.
/// </summary>
/// <param name="es">Style to return white space for.</param>
/// <returns></returns>
public static int LeftWhiteSpace(ElementStyle es)
{
return ElementStyleLayout.StyleSpacing(es,eSpacePart.Border | eSpacePart.Margin | eSpacePart.Padding,eStyleSide.Left);
}
/// <summary>
/// Returns total white space for right side of the style. Whitespace is the space between the edge of the element and inner content of the element.
/// </summary>
/// <param name="es">Style to return white space for.</param>
/// <returns></returns>
public static int RightWhiteSpace(ElementStyle es)
{
return ElementStyleLayout.StyleSpacing(es,eSpacePart.Border | eSpacePart.Margin | eSpacePart.Padding,eStyleSide.Right);
}
/// <summary>
/// Returns total white space for top side of the style. Whitespace is the space between the edge of the element and inner content of the element.
/// </summary>
/// <param name="es">Style to return white space for.</param>
/// <returns></returns>
public static int TopWhiteSpace(ElementStyle es)
{
return ElementStyleLayout.StyleSpacing(es,eSpacePart.Border | eSpacePart.Margin | eSpacePart.Padding,eStyleSide.Top);
}
/// <summary>
/// Returns total white space for top side of the style. Whitespace is the space between the edge of the element and inner content of the element.
/// </summary>
/// <param name="es">Style to return white space for.</param>
/// <returns></returns>
public static int BottomWhiteSpace(ElementStyle es)
{
return ElementStyleLayout.StyleSpacing(es,eSpacePart.Border | eSpacePart.Margin | eSpacePart.Padding,eStyleSide.Bottom);
}
/// <summary>
/// Returns amount of spacing for specified style parts.
/// </summary>
/// <param name="es">Style to calculate spacing for.</param>
/// <param name="part">Part of the style spacing is calculated for. Values can be combined.</param>
/// <param name="side">Side of the style to use for calculation.</param>
/// <returns></returns>
public static int StyleSpacing(ElementStyle style, eSpacePart part, eStyleSide side)
{
ElementStyle es = ElementStyleDisplay.GetElementStyle(style);
int space=0;
if((part & eSpacePart.Margin)==eSpacePart.Margin)
{
switch(side)
{
case eStyleSide.Bottom:
space+=es.MarginBottom;
break;
case eStyleSide.Left:
space+=es.MarginLeft;
break;
case eStyleSide.Right:
space+=es.MarginRight;
break;
case eStyleSide.Top:
space+=es.MarginTop;
break;
}
}
if((part & eSpacePart.Padding)==eSpacePart.Padding)
{
switch(side)
{
case eStyleSide.Bottom:
space+=es.PaddingBottom;
break;
case eStyleSide.Left:
space+=es.PaddingLeft;
break;
case eStyleSide.Right:
space+=es.PaddingRight;
break;
case eStyleSide.Top:
space+=es.PaddingTop;
break;
}
}
if((part & eSpacePart.Border)==eSpacePart.Border)
{
switch(side)
{
case eStyleSide.Bottom:
{
if(es.PaintBottomBorder)
space+=es.BorderBottomWidth;
if (es.BorderBottom == eStyleBorderType.Etched || es.BorderBottom == eStyleBorderType.Double)
space += es.BorderBottomWidth;
break;
}
case eStyleSide.Left:
{
if(es.PaintLeftBorder)
space+=es.BorderLeftWidth;
if (es.BorderLeft == eStyleBorderType.Etched || es.BorderLeft == eStyleBorderType.Double)
space += es.BorderLeftWidth;
break;
}
case eStyleSide.Right:
{
if(es.PaintRightBorder)
space+=es.BorderRightWidth;
if (es.BorderRight == eStyleBorderType.Etched || es.BorderRight == eStyleBorderType.Double)
space += es.BorderRightWidth;
break;
}
case eStyleSide.Top:
{
if(es.PaintTopBorder)
space+=es.BorderTopWidth;
if (es.BorderTop == eStyleBorderType.Etched || es.BorderTop == eStyleBorderType.Double)
space += es.BorderTopWidth;
break;
}
}
}
return space;
}
/// <summary>
/// Gets inner rectangle taking in account style padding, margins and border.
/// </summary>
public static Rectangle GetInnerRect(ElementStyle style, Rectangle bounds)
{
bounds.X += LeftWhiteSpace(style);
bounds.Width -= HorizontalStyleWhiteSpace(style);
bounds.Y += TopWhiteSpace(style);
bounds.Height -= VerticalStyleWhiteSpace(style);
return bounds;
}
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System.Windows.Forms;
using System.ComponentModel.Design;
namespace DevComponents.Tree
{
/// <summary>
/// Represents type editor for ElementStyle used for Windows Forms design-time support.
/// </summary>
public class ElementStyleTypeEditor:System.Drawing.Design.UITypeEditor
{
#region Private Variables
private IWindowsFormsEditorService m_EditorService = null;
private const string OPTION_CREATE="Create new style";
private const string OPTION_REMOVE="Remove style";
#endregion
#region Internal Implementation
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context != null
&& context.Instance != null
&& provider != null)
{
ElementStyle es=value as ElementStyle;
m_EditorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
if(m_EditorService!=null)
{
ListBox lb=new ListBox();
lb.SelectedIndexChanged+=new EventHandler(this.SelectedChanged);
if(es==null)
lb.Items.Add(OPTION_CREATE);
else
lb.Items.Add(OPTION_REMOVE);
m_EditorService.DropDownControl(lb);
IDesignerHost dh=(IDesignerHost)provider.GetService(typeof(IDesignerHost));
if(lb.SelectedItem!=null && dh!=null)
{
if(lb.SelectedItem.ToString()==OPTION_CREATE)
{
value=dh.CreateComponent(typeof(ElementStyle)) as ElementStyle;
}
else if(lb.SelectedItem.ToString()==OPTION_REMOVE)
{
value=null;
dh.DestroyComponent(es);
}
}
}
}
return value;
}
private void SelectedChanged(object sender, EventArgs e)
{
if(m_EditorService!=null)
m_EditorService.CloseDropDown();
}
/// <summary>
/// Gets the editor style used by the EditValue method.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param>
/// <returns>A UITypeEditorEditStyle value that indicates the style of editor used by EditValue. If the UITypeEditor does not support this method, then GetEditStyle will return None</returns>
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
if (context != null && context.Instance != null)
{
return UITypeEditorEditStyle.DropDown;
}
return base.GetEditStyle(context);
}
#endregion
}
}

View File

@@ -0,0 +1,648 @@
using System;
namespace DevComponents.Tree
{
/// <summary>Specifies the way background image is displayed on background.</summary>
public enum eStyleBackgroundImage:int
{
/// <summary>Image is stretched to fill the background</summary>
Stretch=0,
/// <summary>Image is centered inside the background</summary>
Center=1,
/// <summary>Image is tiled inside the background</summary>
Tile=2,
/// <summary>
/// Image is drawn in top left corner of container space.
/// </summary>
TopLeft=3,
/// <summary>
/// Image is drawn in top right corner of container space.
/// </summary>
TopRight=4,
/// <summary>
/// Image is drawn in bottom left corner of container space.
/// </summary>
BottomLeft=5,
/// <summary>
/// Image is drawn in bottom right corner of container space.
/// </summary>
BottomRight=6
}
/// <summary>Indicates alignment of a part of the cell like image or check box in relation to the text.</summary>
public enum eCellPartAlignment:int
{
/// <summary>
/// Part is aligned to the left center of the text assuming left-to-right
/// orientation.
/// </summary>
NearCenter=0,
/// <summary>
/// Part is aligned to the right center of the text assuming left-to-right
/// orientation.
/// </summary>
FarCenter=1,
/// <summary>
/// Part is aligned to the top left of the text assuming left-to-right
/// orientation.
/// </summary>
NearTop=2,
/// <summary>Part is aligned above the text and centered.</summary>
CenterTop=3,
/// <summary>
/// Part is aligned to the top right of the text assuming left-to-right
/// orientation.
/// </summary>
FarTop=4,
/// <summary>
/// Part is aligned to the bottom left of the text assuming left-to-right
/// orientation.
/// </summary>
NearBottom=5,
/// <summary>Part is aligned below the text and centered.</summary>
CenterBottom=6,
/// <summary>
/// Part is aligned to the bottom right of the text assuming left-to-right
/// orientation.
/// </summary>
FarBottom=7
}
/// <summary>
/// Specifies the alignment of a text string relative to its element's rectangle.
/// </summary>
public enum eStyleTextAlignment
{
/// <summary>
/// Specifies the text be aligned near from the origin position of the element's rectangle. In a left-to-right layout, the near position is left. In a right-to-left layout, the near position is right.
/// </summary>
Near=System.Drawing.StringAlignment.Near,
/// <summary>
/// Specifies that text is aligned in the center of the element's rectangle.
/// </summary>
Center=System.Drawing.StringAlignment.Center,
/// <summary>
/// Specifies that text is aligned far from the origin position of the element's rectangle. In a left-to-right layout, the far position is right. In a right-to-left layout, the far position is left.
/// </summary>
Far=System.Drawing.StringAlignment.Far
}
/// <summary>
/// Specifies how to trim characters from a text that does not completely fit into a element's shape.
/// </summary>
public enum eStyleTextTrimming
{
/// <summary>
/// Specifies that the text is trimmed to the nearest character.
/// </summary>
Character=System.Drawing.StringTrimming.Character,
/// <summary>
/// Specifies that the text is trimmed to the nearest character, and an ellipsis is inserted at the end of a trimmed line.
/// </summary>
EllipsisCharacter=System.Drawing.StringTrimming.EllipsisCharacter,
/// <summary>
/// The center is removed from trimmed lines and replaced by an ellipsis. The algorithm keeps as much of the last slash-delimited segment of the line as possible.
/// </summary>
EllipsisPath=System.Drawing.StringTrimming.EllipsisPath,
/// <summary>
/// Specifies that text is trimmed to the nearest word, and an ellipsis is inserted at the end of a trimmed line.
/// </summary>
EllipsisWord=System.Drawing.StringTrimming.EllipsisWord,
/// <summary>
/// Specifies no trimming.
/// </summary>
None=System.Drawing.StringTrimming.None,
/// <summary>
/// Specifies that text is trimmed to the nearest word.
/// </summary>
Word=System.Drawing.StringTrimming.Word
}
/// <summary>
/// Specifies the border type for style element.
/// </summary>
public enum eStyleBorderType:int
{
/// <summary>Indicates no border</summary>
None,
/// <summary>Border is a solid line</summary>
Solid,
/// <summary>Border is a solid dash line</summary>
Dash,
/// <summary>Border is solid dash-dot line</summary>
DashDot,
/// <summary>Border is solid dash-dot-dot line</summary>
DashDotDot,
/// <summary>Border consists of dots</summary>
Dot,
/// <summary>Etched Border</summary>
Etched,
/// <summary>Double Border</summary>
Double
}
/// <summary>
/// Indicates absolute vertical alignment of the content.
/// </summary>
internal enum eVerticalAlign
{
/// <summary>
/// Content is aligned to the top
/// </summary>
Top,
/// <summary>
/// Content is aligned in the middle
/// </summary>
Middle,
/// <summary>
/// Content is aligned at the bottom
/// </summary>
Bottom
}
/// <summary>
/// Indicates absolute horizontal alignment
/// </summary>
internal enum eHorizontalAlign
{
/// <summary>
/// Content is left aligned
/// </summary>
Left,
/// <summary>
/// Content is centered
/// </summary>
Center,
/// <summary>
/// Content is right aligned
/// </summary>
Right
}
/// <summary>
/// Indicates prefered node layout position on Map tree layout when node is the child node of the top-level root node.
/// </summary>
public enum eMapPosition
{
/// <summary>
/// Node is positioned based on default algorithm.
/// </summary>
Default,
/// <summary>
/// Sub-root node and all nodes after it are positioned to the left of the root.
/// </summary>
Near,
/// <summary>
/// Sub-root node and all nodes before it are positioned to the right of the root.
/// </summary>
Far
}
/// <summary>
/// Indicates corner type for the border around visual element.
/// </summary>
public enum eCornerType
{
/// <summary>
/// Specifies that corner type is inherited from parent setting.
/// </summary>
Inherit,
/// <summary>
/// Specifies square corner.
/// </summary>
Square,
/// <summary>
/// Specifies rounded corner.
/// </summary>
Rounded,
/// <summary>
/// Specifies diagonal corner.
/// </summary>
Diagonal
}
/// <summary>
/// Specifies the column header visibility for the node.
/// </summary>
public enum eNodeHeaderVisibility
{
/// <summary>
/// Column header is automatically shown/hidden based on the node's position in the tree. When
/// Node is first child node i.e. with index=0 the header will be shown, otherwise header will
/// be hidden.
/// </summary>
Automatic,
/// <summary>
/// Column header is always displayed regardless of node's position.
/// </summary>
AlwaysShow,
/// <summary>
/// Column header is always hidden regardless of node's position.
/// </summary>
AlwaysHide
}
/// <summary>
/// Indicates the part of the node.
/// </summary>
internal enum eNodeRectanglePart
{
/// <summary>
/// Bounds of complete node content except expand button. This also includes the child node bounds if node is expanded.
/// </summary>
NodeContentBounds,
/// <summary>
/// Bounds of the expand button which collapses/expands the node.
/// </summary>
ExpandBounds,
/// <summary>
/// Bounds of all child nodes of give node.
/// </summary>
ChildNodeBounds,
/// <summary>
/// Bounds for cells inside a node.
/// </summary>
CellsBounds,
/// <summary>
/// Complete node bounds including expand button.
/// </summary>
NodeBounds,
/// <summary>
/// Bounds of the command button.
/// </summary>
CommandBounds
}
/// <summary>
/// Indicates the part of the cell.
/// </summary>
internal enum eCellRectanglePart
{
/// <summary>
/// Bounds of check box or Rectangle.Empty if there is no check-box.
/// </summary>
CheckBoxBounds,
/// <summary>
/// Bounds of image inside the cell or Rectangle.Empty if there is no image.
/// </summary>
ImageBounds,
/// <summary>
/// Text bounds inside of cell.
/// </summary>
TextBounds,
/// <summary>
/// Cell bounds
/// </summary>
CellBounds
}
/// <summary>
/// Indicates part of the node mouse is placed over.
/// </summary>
internal enum eMouseOverNodePart
{
/// <summary>
/// Mouse is not over any node part.
/// </summary>
None,
/// <summary>
/// Mouse is placed over the node.
/// </summary>
Node,
/// <summary>
/// Mouse is placed over node expand button.
/// </summary>
Expand,
/// <summary>
/// Mouse is placed over the cell.
/// </summary>
Cell,
/// <summary>
/// Mouse is placed over the command button.
/// </summary>
Command
}
/// <summary>
/// Indicates white-space part of the style.
/// </summary>
[Flags()]
public enum eSpacePart
{
/// <summary>
/// Represents style padding.
/// </summary>
Padding=1,
/// <summary>
/// Represents style border.
/// </summary>
Border=2,
/// <summary>
/// Represents style margin.
/// </summary>
Margin=4
}
/// <summary>
/// Indicates the style side.
/// </summary>
public enum eStyleSide
{
/// <summary>
/// Specifies left side of the style.
/// </summary>
Left,
/// <summary>
/// Specifies right side of the style.
/// </summary>
Right,
/// <summary>
/// Specifies top side of the style.
/// </summary>
Top,
/// <summary>
/// Specifies bottom side of the style.
/// </summary>
Bottom
}
/// <summary>
/// Indicates the visibility of node expand part which allows user to expand/collaps node.
/// </summary>
public enum eNodeExpandVisibility
{
/// <summary>
/// Default setting which indicates that when node has child nodes expand part is visible otherwise it is hidden.
/// </summary>
Auto,
/// <summary>
/// Expand part is always visible regardless of whether child nodes are present or not.
/// </summary>
Visible,
/// <summary>
/// Expand part is always hidden regardless of whether child nodes are present or not.
/// </summary>
Hidden
}
/// <summary>
/// Specifies the action that raised a TreeGXEventArgs event
/// </summary>
public enum eTreeAction
{
/// <summary>
/// The event was caused by a keystroke.
/// </summary>
Keyboard,
/// <summary>
/// The event was caused by a mouse operation.
/// </summary>
Mouse,
/// <summary>
/// The event was caused by the Node collapsing.
/// </summary>
Collapse,
/// <summary>
/// The event was caused by the Node expanding.
/// </summary>
Expand,
/// <summary>
/// The event is caused programmatically from user code.
/// </summary>
Code
}
/// <summary>
/// Specifies node connector type. Node connector is the type of the line/connection that is drawn to connect child node to it's parent node.
/// </summary>
public enum eNodeConnectorType
{
/// <summary>
/// Curved line connector type.
/// </summary>
Curve,
/// <summary>
/// Straight line connector type.
/// </summary>
Line
}
/// <summary>
/// Specifies the cap style with which the connector line will start or end.
/// </summary>
public enum eConnectorCap
{
/// <summary>
/// Specifies no cap.
/// </summary>
None,
/// <summary>
/// Round cap type.
/// </summary>
Ellipse,
/// <summary>
/// Arrow cap type.
/// </summary>
Arrow
}
/// <summary>
/// Specifies the layout type used to position the cells within the nodes.
/// </summary>
public enum eCellLayout
{
/// <summary>
/// Specifies that default setting is to be used for cell layout. Default is Horizontal. When set to default on the Node, setting from Tree control is used.
/// </summary>
Default,
/// <summary>Horizontal layout positions the cells horizontally next to each other.</summary>
Horizontal,
/// <summary>
/// Vertical layout positions cell vertically on top of each other.
/// </summary>
Vertical
}
/// <summary>
/// Specifies the layout type used to position the parts of the cell like image, checkbox and text.
/// </summary>
public enum eCellPartLayout
{
/// <summary>
/// Specifies that default setting is to be used for cell parts layout. Default is Horizontal. When set to default on the Cell, setting from Tree control is used.
/// </summary>
Default,
/// <summary>Horizontal layout positions the parts of the cell horizontally next to each other.</summary>
Horizontal,
/// <summary>
/// Vertical layout positions parts of the cell vertically on top of each other.
/// </summary>
Vertical
}
/// <summary>
/// Specifies the color scheme loaded by ColorScheme object.
/// </summary>
public enum eColorSchemeStyle
{
/// <summary>
/// Indicates Office 2003 like color scheme.
/// </summary>
Office2003,
/// <summary>
/// Indicates Office XP like color scheme.
/// </summary>
OfficeXP,
/// <summary>
/// Indicates VS.NET 2005 like color scheme.
/// </summary>
VS2005
}
/// <summary>
/// Specifies the currently selected system color scheme if running on Windows XP.
/// </summary>
internal enum eWinXPColorScheme
{
/// <summary>
/// Color scheme cannot be determined.
/// </summary>
Undetermined,
/// <summary>
/// Blue color scheme.
/// </summary>
Blue,
/// <summary>
/// Olive green color scheme.
/// </summary>
OliveGreen,
/// <summary>
/// Silver color scheme.
/// </summary>
Silver
}
/// <summary>
/// Specifies the flow of diagram layout related to the root node.
/// </summary>
public enum eDiagramFlow
{
/// <summary>
/// Nodes are positioned from left to right with root node being the left-most node.
/// </summary>
LeftToRight,
/// <summary>
/// Nodes are positioned from right to left with root node being the right-most
/// node.
/// </summary>
RightToLeft,
/// <summary>
/// Nodes are positioned from top to bottom with root node being the top node.
/// </summary>
TopToBottom,
/// <summary>
/// Nodes are positioned from bottom to top with root node being bottom node.
/// </summary>
BottomToTop
}
/// <summary>
/// Specifies the flow of the map layout.
/// </summary>
public enum eMapFlow
{
/// <summary>
/// Nodes are arranged around the root node.
/// </summary>
Spread,
/// <summary>
/// Nodes are arranged from below the root node.
/// </summary>
TopToBottom,
/// <summary>
/// Nodes are arranged above the root node.
/// </summary>
BottomToTop,
/// <summary>
/// Nodes are arranged to the right of the root node.
/// </summary>
LeftToRight,
/// <summary>
/// Nodes are arranged to the left of the root node.
/// </summary>
RightToLeft
}
/// <summary>
/// Specifies the type of the expand button.
/// </summary>
public enum eExpandButtonType
{
/// <summary>
/// Indicates elliptical expand button.
/// </summary>
Ellipse,
/// <summary>
/// Indicates rectangular expand button.
/// </summary>
Rectangle,
/// <summary>
/// Indicates that images are used for expand button. See
/// </summary>
Image
}
/// <summary>
/// Specifies the visual style for the tree control.
/// </summary>
public enum eVisualStyle
{
/// <summary>
/// Indicates default visual style.
/// </summary>
Default
}
/// <summary>
/// Specifies the layout type for the nodes.
/// </summary>
public enum eNodeLayout
{
/// <summary>
/// Nodes are arranged arround root node in map format.
/// </summary>
Map,
/// <summary>
/// Nodes are arranged from left-to-right in diagram format.
/// </summary>
Diagram
}
/// <summary>
/// Specifies renderer type used to render nodes.
/// </summary>
public enum eNodeRenderMode
{
/// <summary>
/// Specifies default renderer which allows most customization through TreeGX
/// properties. Default renderer integrates with the Style architecture to provide
/// customization on renderer behavior.
/// </summary>
Default,
/// <summary>
/// <para>Specifies professional renderer. Professional renderer is custom renderer
/// which does not rely on Style architecture for customization of renderer appearance
/// since it provides much richer appearance than Default renderer.</para>
/// <para>Professional renderer colors can be controls through
/// NodeProfessionalColorTable object which is exposed by
/// NodeProfessionalRenderer.ColorTable property.</para>
/// </summary>
Professional,
/// <summary>
/// Specifies that custom renderer is used. When set you must also set NodeRenderer
/// to renderer you want to use.
/// </summary>
Custom
}
}

View File

@@ -0,0 +1,83 @@
using System;
using DevComponents.Tree.Display;
namespace DevComponents.Tree
{
/// <summary>
/// Defines the delegate for TreeGX cell based action events.
/// </summary>
public delegate void TreeGXCellEventHandler(object sender, TreeGXCellEventArgs e);
/// <summary>
/// Defines the delegate for TreeGX cell based action events.
/// </summary>
public delegate void TreeGXCellCancelEventHandler(object sender, TreeGXCellCancelEventArgs e);
/// <summary>
/// Defines the delegate for TreeGX node based action events that can be cancelled.
/// </summary>
public delegate void TreeGXNodeCancelEventHandler(object sender, TreeGXNodeCancelEventArgs e);
/// <summary>
/// Defines the delegate for TreeGX node based action events.
/// </summary>
public delegate void TreeGXNodeEventHandler(object sender, TreeGXNodeEventArgs e);
/// <summary>
/// Defines delegate for Command button events.
/// </summary>
public delegate void CommandButtonEventHandler(object sender, CommandButtonEventArgs e);
/// <summary>
/// Defines delegate for label editing events.
/// </summary>
public delegate void CellEditEventHandler(object sender, CellEditEventArgs e);
/// <summary>
/// Defines the delegate for TreeGX node based action events.
/// </summary>
public delegate void TreeGXNodeCollectionEventHandler(object sender, TreeGXNodeCollectionEventArgs e);
/// <summary>
/// Defines the delegate for BeforeNodeDrop and AfterNodeDrop events
/// </summary>
public delegate void TreeGXDragDropEventHandler(object sender, TreeGXDragDropEventArgs e);
/// <summary>
/// Defines the delegate for mouse based node events
/// </summary>
public delegate void TreeGXNodeMouseEventHandler(object sender, TreeGXNodeMouseEventArgs e);
/// <summary>
/// Defines delegate for node rendering events.
/// </summary>
public delegate void NodeRendererEventHandler(object sender, NodeRendererEventArgs e);
/// <summary>
/// Defines delegate for cell rendering events.
/// </summary>
public delegate void NodeCellRendererEventHandler(object sender, NodeCellRendererEventArgs e);
/// <summary>
/// Defines delegate for RenderExpandPart event.
/// </summary>
public delegate void NodeExpandPartRendererEventHandler(object sender, NodeExpandPartRendererEventArgs e);
/// <summary>
/// Defines delegate for RenderExpandPart event.
/// </summary>
public delegate void NodeCommandPartRendererEventHandler(object sender, NodeCommandPartRendererEventArgs e);
/// <summary>
/// Defines delegate for RenderExpandPart event.
/// </summary>
public delegate void SelectionRendererEventHandler(object sender, SelectionRendererEventArgs e);
/// <summary>
/// Defines delegate for RenderConnector event.
/// </summary>
public delegate void ConnectorRendererEventHandler(object sender, ConnectorRendererEventArgs e);
/// <summary>
/// Defines delegate for TreeBackgroundRenderer events.
/// </summary>
public delegate void TreeBackgroundRendererEventHandler(object sender, TreeBackgroundRendererEventArgs e);
}

View File

@@ -0,0 +1,36 @@
using System;
namespace DevComponents.Tree
{
/// <summary>
/// Provides more information about MarkupLinkClick event.
/// </summary>
public class MarkupLinkClickEventArgs : EventArgs
{
/// <summary>
/// Gets the value of href attribute from the markup link that was clicked.
/// </summary>
public readonly string HRef = "";
/// <summary>
/// Gets the value of name attribute from the markup link that was clicked.
/// </summary>
public readonly string Name = "";
/// <summary>
/// Creates new instance of the object.
/// </summary>
/// <param name="name">Value of name attribute.</param>
/// <param name="href">Value of href attribute.</param>
public MarkupLinkClickEventArgs(string name, string href)
{
this.HRef = href;
this.Name = name;
}
}
/// <summary>
/// Defines delegate for MarkupLinkClick event.
/// </summary>
public delegate void MarkupLinkClickEventHandler(object sender, MarkupLinkClickEventArgs e);
}

View File

@@ -0,0 +1,38 @@
using System;
namespace DevComponents.Tree
{
/// <summary>
/// Represents arguments for SerializeNode event which allows you to add custom serialization data to definitions saved by control.
/// </summary>
public class SerializeNodeEventArgs : EventArgs
{
/// <summary>
/// Gets reference to the node being serialized or de-serialized.
/// </summary>
public Node Node = null;
/// <summary>
/// Gets reference to instance of XmlElement that item is serialized to or is being de-serialized from. You should not change any data directly on this element.
/// </summary>
public System.Xml.XmlElement ItemXmlElement = null;
/// <summary>
/// Gets the reference to XmlElement that you can serialize to or de-serialize any custom data from. You can add child elements or set the attributes on
/// this XmlElement when handling SerializeItem event. When handling DeserializeItem event you can load your data from this element.
/// </summary>
public System.Xml.XmlElement CustomXmlElement = null;
public SerializeNodeEventArgs(Node node, System.Xml.XmlElement itemXmlElement, System.Xml.XmlElement customXmlElement)
{
this.Node = node;
this.ItemXmlElement = itemXmlElement;
this.CustomXmlElement = customXmlElement;
}
}
/// <summary>
/// Defines delegate for SerializeItem event.
/// </summary>
public delegate void SerializeNodeEventHandler(object sender, SerializeNodeEventArgs e);
}

View File

@@ -0,0 +1,40 @@
using System;
using System.ComponentModel;
namespace DevComponents.Tree
{
/// <summary>
/// Represents the table header.
/// </summary>
public class HeaderDefinition
{
private string m_Name="";
private ColumnHeaderCollection m_Columns=new ColumnHeaderCollection();
/// <summary>
/// Default constructor.
/// </summary>
public HeaderDefinition()
{
}
/// <summary>
/// Gets the reference to the collection that contains the columns associated with header.
/// </summary>
[Browsable(true),Category("Columns"),Description("Gets the reference to the collection that contains the columns associated with header."),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ColumnHeaderCollection Columns
{
get {return m_Columns;}
}
/// <summary>
/// Gets or sets the name associated with this header definition.
/// </summary>
[Browsable(true),Category("Design"),Description("Indicates name associated with this header definition."),DefaultValue("")]
public string Name
{
get {return m_Name;}
set {m_Name=value;}
}
}
}

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections;
using System.ComponentModel;
namespace DevComponents.Tree
{
/// <summary>
/// Represents collection for HeaderDefinition objects.
/// </summary>
public class HeadersCollection:CollectionBase
{
#region Private Variables
private TreeGX m_Parent=null;
#endregion
#region Internal Implementation
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public TreeGX Parent
{
get {return m_Parent;}
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">HeaderDefinition that is parent of this collection.</param>
internal void SetParent(TreeGX parent)
{
m_Parent=parent;
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="ch">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(HeaderDefinition ch)
{
return List.Add(ch);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public HeaderDefinition this[int index]
{
get {return (HeaderDefinition)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, HeaderDefinition value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(HeaderDefinition value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(HeaderDefinition value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(HeaderDefinition value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(HeaderDefinition[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the HeaderDefinition array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(HeaderDefinition[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
base.OnClear();
}
public HeaderDefinition GetByName(string name)
{
foreach(HeaderDefinition d in this.List)
{
if(d.Name==name)
return d;
}
return null;
}
#endregion
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace DevComponents.Tree.Helpers
{
/// <summary>
/// Defines various system information based helper functions.
/// </summary>
internal static class SystemHelpers
{
#region Private Variables
private static bool _ThemedOS = false;
private static bool _SupportsAnimation = false;
private static bool _IsWindowsXP = false;
private static bool _IsVista = false;
private static bool _IsWindows7 = false;
#endregion
#region Internal Implementation
static SystemHelpers()
{
WinApi.OSVERSIONINFO os = new WinApi.OSVERSIONINFO();
os.dwOSVersionInfoSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(WinApi.OSVERSIONINFO));
WinApi.GetVersionEx(ref os);
if (os.dwPlatformId == 2 && os.dwMajorVersion == 4)
_SupportsAnimation = false;
if (os.dwMajorVersion == 5 && os.dwMinorVersion >= 1 && os.dwPlatformId == 2 ||
os.dwMajorVersion > 5 && os.dwPlatformId == 2)
_ThemedOS = System.Windows.Forms.OSFeature.Feature.IsPresent(System.Windows.Forms.OSFeature.Themes);
Version osVersion = System.Environment.OSVersion.Version;
_IsWindowsXP = osVersion.Major <= 5;
_IsVista = osVersion.Major >= 6;
_IsWindows7 = osVersion.Major >= 6 && osVersion.Minor >= 1 && osVersion.Build >= 7000;
}
public static bool ThemedOS
{
get { return _ThemedOS; }
set
{
_ThemedOS = value;
}
}
public static bool SupportsAnimation
{
get { return _SupportsAnimation; }
set
{
_SupportsAnimation = value;
}
}
public static bool IsWindowsXP
{
get { return _IsWindowsXP; }
set
{
_IsWindowsXP = value;
}
}
public static bool IsVista
{
get { return _IsVista; }
set
{
_IsVista = value;
}
}
public static bool IsWindows7
{
get { return _IsWindows7; }
set
{
_IsWindows7 = value;
}
}
#endregion
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Text;
namespace DevComponents.DotNetBar
{
/// <summary>
/// Defines the provider for the element style classes support.
/// </summary>
public interface IElementStyleClassProvider
{
/// <summary>
/// Returns the instance of the ElementStyle with given class name or null if there is no class with that name defined.
/// </summary>
/// <param name="className">Class name. See static members of ElementStyleClassKeys class for the list of available keys.</param>
/// <returns>Instance of ElementStyle for given class name or null if class cannot be found.</returns>
ElementStyle GetClass(string className);
}
}

View File

@@ -0,0 +1,26 @@
using System;
namespace DevComponents.Tree
{
/// <summary>
/// Specifies the notification interface that node uses to communicate status changes to it's parent tree.
/// </summary>
public interface INodeNotify
{
/// <summary>Called when Node.Expanded property has changed.</summary>
/// <param name="node">Node which Expanded property has changed.</param>
void ExpandedChanged(Node node);
/// <summary>Called before node is collapsed</summary>
/// <param name="e">Context information.</param>
void OnBeforeCollapse(TreeGXNodeCancelEventArgs e);
/// <summary>Called before node is expanded</summary>
/// <param name="e">Context information.</param>
void OnBeforeExpand(TreeGXNodeCancelEventArgs e);
/// <summary>Called after node is collapsed.</summary>
/// <param name="e">Context information.</param>
void OnAfterCollapse(TreeGXNodeEventArgs e);
/// <summary>Called after node is expanded</summary>
/// <param name="e">Context information</param>
void OnAfterExpand(TreeGXNodeEventArgs e);
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.ComponentModel;
using System.Windows.Forms.ComponentModel;
using System.Windows.Forms.Design;
namespace DevComponents.Tree
{
/// <summary>
/// Represents the class used by windows forms editor for picking an image from image list.
/// </summary>
public class ImageIndexEditor:UITypeEditor
{
private ImageEditor m_ImageEditor;
private System.Windows.Forms.ImageList m_ImageList=null;
public ImageIndexEditor():base()
{
m_ImageEditor=System.ComponentModel.TypeDescriptor.GetEditor(typeof(System.Drawing.Image),typeof(UITypeEditor)) as ImageEditor;
}
public override bool GetPaintValueSupported(ITypeDescriptorContext context)
{
return true;
}
public override void PaintValue(PaintValueEventArgs e)
{
try
{
if(e==null || e.Value==null)
return;
int iIndex=(int)e.Value;
System.Drawing.Image img=this.GetImage(e.Context,iIndex);
if(img==null)
return;
PaintValueEventArgs pi=new PaintValueEventArgs(e.Context,img,e.Graphics,e.Bounds);
m_ImageEditor.PaintValue(pi);
//m_ImageEditor.PaintValue(img,e.Graphics,e.Bounds);
}
catch{}
}
private System.Drawing.Image GetImage(System.ComponentModel.ITypeDescriptorContext context,int index)
{
if(m_ImageList!=null && index>=0 && index<=m_ImageList.Images.Count)
{
return m_ImageList.Images[index];
}
if(context==null)
return null;
object o=context.Instance;
if(o==null)
return null;
System.ComponentModel.PropertyDescriptorCollection pd=System.ComponentModel.TypeDescriptor.GetProperties(o);
if(pd==null)
return null;
foreach(System.ComponentModel.PropertyDescriptor prop in pd)
{
if(prop.PropertyType==typeof(System.Windows.Forms.ImageList))
{
m_ImageList=prop.GetValue(o) as System.Windows.Forms.ImageList;
if(m_ImageList!=null && index>=0 && index<=m_ImageList.Images.Count)
{
return m_ImageList.Images[index];
}
break;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,57 @@
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace DevComponents.Tree.Interop
{
/// <summary>
/// Provides WinApi functions to rest of the application.
/// </summary>
internal class WinApi
{
#region API Calls Declaration
[DllImport("user32")]
private static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT tme);
[StructLayout(LayoutKind.Sequential)]
private struct TRACKMOUSEEVENT
{
public int cbSize;
public uint dwFlags;
public int dwHoverTime;
public int hwndTrack;
}
// Track Mouse Event Flags
private const uint
TME_HOVER=0x00000001,
TME_LEAVE=0x00000002,
TME_NONCLIENT=0x00000010,
TME_QUERY=0x40000000,
TME_CANCEL=0x80000000,
HOVER_DEFAULT=0xFFFFFFFF;
#endregion
#region Functions
/// <summary>
/// Resets Hoover timer for specified control.
/// </summary>
public static void ResetHover(System.Windows.Forms.Control c)
{
if (c==null || !c.IsHandleCreated)
return;
// We need to reset hover thing since it is fired only first time mouse hovers inside the window and we need it for each of our items
TRACKMOUSEEVENT tme = new TRACKMOUSEEVENT();
tme.dwFlags = TME_QUERY;
tme.hwndTrack = (int)c.Handle;
tme.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(tme);
TrackMouseEvent(ref tme);
tme.dwFlags = tme.dwFlags | TME_HOVER;
TrackMouseEvent(ref tme);
}
#endregion
}
}

View File

@@ -0,0 +1,148 @@
using System;
using System.Windows.Forms;
namespace DevComponents.Tree
{
/// <summary>
/// Provides TreeGX Keyboard handling.
/// </summary>
internal class KeyNavigation
{
public static void KeyDown(TreeGX tree, KeyEventArgs e)
{
switch(e.KeyCode)
{
case Keys.Enter:
{
EnterKeyDown(tree, e);
e.Handled = true;
break;
}
case Keys.Up:
case Keys.Down:
case Keys.Left:
case Keys.Right:
{
NavigateKeyDown(tree, e);
e.Handled = true;
break;
}
}
}
public static void EnterKeyDown(TreeGX tree, KeyEventArgs e)
{
if(tree.SelectedNode!=null && tree.SelectedNode.Nodes.Count>0)
{
tree.SelectedNode.Toggle(eTreeAction.Keyboard);
}
}
public static void NavigateKeyDown(TreeGX tree, KeyEventArgs e)
{
if(tree.SelectedNode==null)
{
if(tree.DisplayRootNode!=null)
tree.SelectNode(tree.DisplayRootNode, eTreeAction.Keyboard);
else if(tree.Nodes.Count>0)
tree.SelectNode(tree.Nodes[0], eTreeAction.Keyboard);
return;
}
Node node=tree.SelectedNode;
if(e.KeyCode == Keys.Down || e.KeyCode == Keys.Right && NodeOperations.GetVisibleChildNodesCount(node) == 0)
{
int currentCell = 0;
if (node != null && node.SelectedCell != null) currentCell = node.Cells.IndexOf(node.SelectedCell);
Node nextNode = NodeOperations.GetNextVisibleNode(node);
//// Adjust nextNode so the multi-selection is proper
//if ((e.KeyData & Keys.Shift) == Keys.Shift && tree.MultiSelect && tree.SelectedNodes.Count > 1)
//{
// if (tree.SelectedNodes[0].Bounds.Y > tree.SelectedNodes[tree.SelectedNodes.Count - 1].Bounds.Y)
// nextNode = tree.SelectedNodes[tree.SelectedNodes.Count - 1];
//}
if (nextNode != null)
{
if (!nextNode.CanSelect)
{
int counter = 0;
while (nextNode != null && counter < 100)
{
nextNode = NodeOperations.GetNextVisibleNode(nextNode);
if (nextNode != null && nextNode.CanSelect) break;
}
}
//if ((e.KeyData & Keys.Shift) == Keys.Shift && tree.MultiSelect && tree.SelectedNodes.Count > 0)
//{
// if (tree.MultiSelectRule == eMultiSelectRule.SameParent && tree.SelectedNodes[0].Parent != nextNode.Parent) return true;
// if (nextNode.IsSelected)
// tree.SelectedNodes.Remove(nextNode, eTreeAction.Keyboard);
// else
// tree.SelectedNodes.Add(nextNode, eTreeAction.Keyboard);
// nextNode.EnsureVisible();
//}
//else
{
tree.SelectNode(nextNode, eTreeAction.Keyboard);
//if (tree.SelectionPerCell && currentCell < nextNode.Cells.Count && currentCell > 0)
// nextNode.SetSelectedCell(nextNode.Cells[currentCell], eTreeAction.Keyboard);
}
}
}
else if(e.KeyCode == Keys.Up || e.KeyCode == Keys.Left && node.Parent == null)
{
int currentCell = 0;
if (node != null && node.SelectedCell != null) currentCell = node.Cells.IndexOf(node.SelectedCell);
Node prevNode = NodeOperations.GetPreviousVisibleNode(node);
if (prevNode != null)
{
if (!prevNode.CanSelect)
{
int counter = 0;
while (prevNode != null && counter < 100)
{
prevNode = NodeOperations.GetPreviousVisibleNode(prevNode);
if (prevNode != null && prevNode.CanSelect) break;
}
}
//if ((e.KeyData & Keys.Shift) == Keys.Shift && tree.MultiSelect && tree.SelectedNodes.Count > 0)
//{
// if (tree.MultiSelectRule == eMultiSelectRule.SameParent && tree.SelectedNodes[0].Parent != prevNode.Parent) return true;
// if (prevNode.IsSelected)
// {
// tree.SelectedNodes.Remove(tree.SelectedNodes[tree.SelectedNodes.Count - 1], eTreeAction.Keyboard);
// }
// else
// tree.SelectedNodes.Add(prevNode, eTreeAction.Keyboard);
// prevNode.EnsureVisible();
//}
//else
if (prevNode != null)
{
tree.SelectNode(prevNode, eTreeAction.Keyboard);
//if (tree.SelectionPerCell && currentCell < prevNode.Cells.Count && currentCell > 0)
// prevNode.SetSelectedCell(prevNode.Cells[currentCell], eTreeAction.Keyboard);
}
}
}
else if(e.KeyCode == Keys.Right)
{
Node childNode = NodeOperations.GetFirstVisibleChildNode(node);
if(childNode!=null)
tree.SelectNode(childNode, eTreeAction.Keyboard);
}
else if(e.KeyCode == Keys.Left)
{
if(node.Parent!=null)
tree.SelectNode(node.Parent, eTreeAction.Keyboard);
}
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Drawing;
namespace DevComponents.Tree.Layout
{
/// <summary>
/// Class that is used to layout column header.
/// </summary>
internal class ColumnHeaderLayout
{
public ColumnHeaderLayout()
{
}
// 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 static int LayoutColumnHeader(NodeLayoutContextInfo layoutInfo,int x, int y, int clientWidth, int cellHorizontalSpacing)
{
Node node=layoutInfo.ContextNode;
int height=0;
foreach(ColumnHeader col in node.NodesColumns)
{
if(!col.Visible)
continue;
if(col.SizeChanged)
{
// Column for child nodes is always placed below the current node and
// is not included in the node's rectangle
Rectangle bounds=Rectangle.Empty;
bounds.X=x;
bounds.Y=y;
if(col.Width.Relative>0)
bounds.Width=(clientWidth*col.Width.Relative)/100-1;
else
bounds.Width=col.Width.Absolute;
if(col.StyleNormal=="" && col.StyleMouseDown=="" && col.StyleMouseOver=="")
{
bounds.Height=layoutInfo.DefaultHeaderSize.Height;
}
else
{
Size sz=Size.Empty;
if(col.StyleNormal!="")
{
ElementStyleLayout.CalculateStyleSize(layoutInfo.Styles[col.StyleNormal],layoutInfo.DefaultFont);
sz=layoutInfo.Styles[col.StyleNormal].Size;
}
if(sz.Height==0)
bounds.Height=layoutInfo.DefaultHeaderSize.Height;
else
bounds.Height=sz.Height;
}
col.SetBounds(bounds);
col.SizeChanged=false;
x+=(bounds.Width+cellHorizontalSpacing);
if(bounds.Height>height)
height=bounds.Height;
}
else if(col.Bounds.Height>height)
height=col.Bounds.Height;
}
return height;
}
}
}

View File

@@ -0,0 +1,608 @@
using System;
using System.Drawing;
namespace DevComponents.Tree
{
namespace Layout
{
/// <summary>
/// Represents class for Node's cell layout.
/// </summary>
internal class CellLayout
{
public CellLayout()
{
}
/// <summary>
/// Offset cell bounds, check box bounds, image bounds and text bounds by specified offset.
/// </summary>
/// <param name="cell">Cell to offset.</param>
/// <param name="x">Horizontal offset in pixels.</param>
/// <param name="y">Vertical offset in pixels.</param>
public void Offset(Cell cell, int x, int y)
{
cell.SetBounds(new Rectangle(cell.BoundsRelative.X+x,cell.BoundsRelative.Y+y,cell.BoundsRelative.Width,cell.BoundsRelative.Height));
if(!cell.CheckBoxBoundsRelative.IsEmpty)
cell.SetCheckBoxBounds(new Rectangle(cell.CheckBoxBoundsRelative.X+x,cell.CheckBoxBoundsRelative.Y+y,cell.CheckBoxBoundsRelative.Width,cell.CheckBoxBoundsRelative.Height));
if(!cell.ImageBoundsRelative.IsEmpty)
cell.SetImageBounds(new Rectangle(cell.ImageBoundsRelative.X+x,cell.ImageBoundsRelative.Y+y,cell.ImageBoundsRelative.Width,cell.ImageBoundsRelative.Height));
if(!cell.TextContentBounds.IsEmpty)
cell.TextContentBounds=new Rectangle(cell.TextContentBounds.X+x,cell.TextContentBounds.Y+y,cell.TextContentBounds.Width,cell.TextContentBounds.Height);
}
public void LayoutSingleCell(LayoutCellInfo info)
{
Size textSize=Size.Empty;
Font font=info.Font;
int height=0;
if(info.LayoutStyle.Font!=null)
font=info.LayoutStyle.Font;
info.ContextCell.OnLayoutCell();
Size largestImageSize = Dpi.Size(info.ContextCell.Images.LargestImageSize);
if(info.ContextCell.HostedControl!=null)
{
Size controlSize=info.ContextCell.HostedControl.Size;
if(!info.ContextCell.HostedControlSize.IsEmpty)
controlSize = info.ContextCell.HostedControlSize;
if(info.CellWidth==0)
textSize=new Size(controlSize.Width,controlSize.Height);
else
{
int availTextWidth=info.CellWidth-
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
textSize=new Size(availTextWidth,controlSize.Height);
}
}
else
{
// Calculate Text Width and Height
if(info.CellWidth==0)
{
if (info.ContextCell.TextMarkupBody == null)
{
string text=info.ContextCell.Text;
if(text!="")
{
if(info.LayoutStyle.WordWrap && info.LayoutStyle.MaximumWidth>0)
textSize=TextDrawing.MeasureString(info.Graphics, text, font, info.LayoutStyle.MaximumWidth);
else if(info.ContextCell.Parent!=null && info.ContextCell.Parent.Style!=null && info.ContextCell.Parent.Style.WordWrap && info.ContextCell.Parent.Style.MaximumWidth>0)
textSize=TextDrawing.MeasureString(info.Graphics, text, font, info.ContextCell.Parent.Style.MaximumWidth);
else
textSize=TextDrawing.MeasureString(info.Graphics, text, font);
}
}
else
{
Size availSize = new Size(1600, 1);
if(info.LayoutStyle.WordWrap && info.LayoutStyle.MaximumWidth>0)
availSize.Width = info.LayoutStyle.MaximumWidth;
else if(info.ContextCell.Parent!=null && info.ContextCell.Parent.Style!=null && info.ContextCell.Parent.Style.WordWrap && info.ContextCell.Parent.Style.MaximumWidth>0)
availSize.Width = info.ContextCell.Parent.Style.MaximumWidth;
TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(info.Graphics, font, Color.Empty, false);
info.ContextCell.TextMarkupBody.Measure(availSize, d);
availSize = info.ContextCell.TextMarkupBody.Bounds.Size;
d.RightToLeft = !info.LeftToRight;
info.ContextCell.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d);
textSize = info.ContextCell.TextMarkupBody.Bounds.Size;
}
}
else
{
int availTextWidth=info.CellWidth-
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
availTextWidth-=largestImageSize.Width;
if(info.ContextCell.CheckBoxVisible)
availTextWidth-=CheckBoxSize.Width;
int cellHeight=font.Height;
if(info.LayoutStyle.WordWrap)
{
cellHeight=info.LayoutStyle.MaximumHeight-info.LayoutStyle.MarginTop-
info.LayoutStyle.MarginBottom-info.LayoutStyle.PaddingTop-info.LayoutStyle.PaddingBottom;
if (info.ContextCell.TextMarkupBody == null)
{
if(availTextWidth>0)
{
if(cellHeight>0)
textSize=TextDrawing.MeasureString(info.Graphics, info.ContextCell.Text,font,new Size(availTextWidth,cellHeight),info.LayoutStyle.TextFormat);
else
textSize=TextDrawing.MeasureString(info.Graphics, info.ContextCell.Text, font, availTextWidth, info.LayoutStyle.TextFormat);
}
}
else
{
Size availSize = new Size(availTextWidth, 1);
TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(info.Graphics, font, Color.Empty, false);
info.ContextCell.TextMarkupBody.Measure(availSize, d);
availSize = info.ContextCell.TextMarkupBody.Bounds.Size;
availSize.Width = availTextWidth;
d.RightToLeft = !info.LeftToRight;
info.ContextCell.TextMarkupBody.Arrange(new Rectangle(0, 0, availSize.Width, availSize.Height), d);
textSize = info.ContextCell.TextMarkupBody.Bounds.Size;
}
}
else
textSize=new Size(availTextWidth,cellHeight);
}
}
if(info.LayoutStyle.WordWrap)
info.ContextCell.WordWrap=true;
else
info.ContextCell.WordWrap=false;
height=(int)Math.Ceiling((double)textSize.Height);
if(info.VerticalPartAlignment)
{
if(largestImageSize.Height>0)
height+=largestImageSize.Height;
if(info.ContextCell.CheckBoxVisible)
height+=CheckBoxSize.Height;
}
else
{
if(largestImageSize.Height>height)
height=largestImageSize.Height;
if(info.ContextCell.CheckBoxVisible && CheckBoxSize.Height>height)
height=CheckBoxSize.Height;
}
Rectangle r=new Rectangle(info.Left+ElementStyleLayout.LeftWhiteSpace(info.LayoutStyle),
info.Top+ElementStyleLayout.TopWhiteSpace(info.LayoutStyle)
,info.CellWidth,height);
if(r.Width==0)
{
if(info.VerticalPartAlignment)
{
r.Width=(int)Math.Ceiling((double)textSize.Width);
if(largestImageSize.Width>r.Width)
r.Width=(largestImageSize.Width+this.ImageTextSpacing);
if(info.ContextCell.CheckBoxVisible && CheckBoxSize.Width>r.Width)
r.Width+=(CheckBoxSize.Width+this.ImageTextSpacing);
}
else
{
r.Width=(int)Math.Ceiling((double)textSize.Width);
if(largestImageSize.Width>0)
r.Width+=(largestImageSize.Width+this.ImageTextSpacing);
if(info.ContextCell.CheckBoxVisible)
r.Width+=(CheckBoxSize.Width+this.ImageTextSpacing);
}
}
// Now that we have cell bounds store them
Rectangle rCellBounds=new Rectangle(info.Left,info.Top,info.CellWidth,r.Height+info.LayoutStyle.MarginTop+info.LayoutStyle.MarginBottom+info.LayoutStyle.PaddingTop+info.LayoutStyle.PaddingBottom);
if(rCellBounds.Width==0)
rCellBounds.Width=r.Width+ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
info.ContextCell.SetBounds(rCellBounds);
// Set Position of the image
if(!largestImageSize.IsEmpty)
{
eVerticalAlign va=GetVerticalAlign(info.ContextCell.ImageAlignment);
eHorizontalAlign ha=GetHorizontalAlign(info.ContextCell.ImageAlignment,info.LeftToRight);
if(info.VerticalPartAlignment)
info.ContextCell.SetImageBounds(AlignContentVertical(largestImageSize, ref r, ha, va, this.ImageTextSpacing));
else
info.ContextCell.SetImageBounds(AlignContent(largestImageSize, ref r, ha, va, this.ImageTextSpacing));
}
else
info.ContextCell.SetImageBounds(Rectangle.Empty);
// Set position of the check box
if(info.ContextCell.CheckBoxVisible)
{
eVerticalAlign va=GetVerticalAlign(info.ContextCell.CheckBoxAlignment);
eHorizontalAlign ha=GetHorizontalAlign(info.ContextCell.CheckBoxAlignment,info.LeftToRight);
if(info.VerticalPartAlignment)
info.ContextCell.SetCheckBoxBounds(AlignContentVertical(this.CheckBoxSize, ref r, ha, va, this.ImageTextSpacing));
else
info.ContextCell.SetCheckBoxBounds(AlignContent(this.CheckBoxSize, ref r, ha, va, this.ImageTextSpacing));
}
else
info.ContextCell.SetCheckBoxBounds(Rectangle.Empty);
// Set position of the text
//info.ContextCell.SetTextBounds(Rectangle.Empty);
if(!textSize.IsEmpty)
info.ContextCell.TextContentBounds=r;
else
info.ContextCell.TextContentBounds=Rectangle.Empty;
}
private Rectangle AlignContent(System.Drawing.Size contentSize, ref Rectangle boundingRectangle, eHorizontalAlign horizAlign, eVerticalAlign vertAlign, int contentSpacing)
{
Rectangle contentRect=new Rectangle(Point.Empty,contentSize);
switch(horizAlign)
{
case eHorizontalAlign.Right:
{
contentRect.X=boundingRectangle.Right-contentRect.Width;
boundingRectangle.Width-=(contentRect.Width+contentSpacing);
break;
}
//case eHorizontalAlign.Left:
default:
{
contentRect.X=boundingRectangle.X;
boundingRectangle.X=contentRect.Right+contentSpacing;
boundingRectangle.Width-=(contentRect.Width+contentSpacing);
break;
}
// case eHorizontalAlign.Center:
// {
// contentRect.X=boundingRectangle.X+(boundingRectangle.Width-contentRect.Width)/2;
// break;
// }
}
switch(vertAlign)
{
case eVerticalAlign.Top:
{
contentRect.Y=boundingRectangle.Y;
break;
}
case eVerticalAlign.Middle:
{
contentRect.Y=boundingRectangle.Y+(boundingRectangle.Height-contentRect.Height)/2;
break;
}
case eVerticalAlign.Bottom:
{
contentRect.Y=boundingRectangle.Bottom-contentRect.Height;
break;
}
}
return contentRect;
}
private Rectangle AlignContentVertical(System.Drawing.Size contentSize, ref Rectangle boundingRectangle, eHorizontalAlign horizAlign, eVerticalAlign vertAlign, int contentSpacing)
{
Rectangle contentRect=new Rectangle(Point.Empty,contentSize);
switch(horizAlign)
{
case eHorizontalAlign.Left:
{
contentRect.X=boundingRectangle.X;
break;
}
case eHorizontalAlign.Right:
{
contentRect.X=boundingRectangle.Right-contentRect.Width;
break;
}
case eHorizontalAlign.Center:
{
contentRect.X=boundingRectangle.X+(boundingRectangle.Width-contentRect.Width)/2;
break;
}
}
switch(vertAlign)
{
case eVerticalAlign.Bottom:
{
contentRect.Y=boundingRectangle.Bottom-contentRect.Height;
boundingRectangle.Height-=(contentRect.Height+contentSpacing);
break;
}
//case eVerticalAlign.Top:
default:
{
contentRect.Y=boundingRectangle.Y;
boundingRectangle.Y=contentRect.Bottom+contentSpacing;
boundingRectangle.Height-=(contentRect.Height+contentSpacing);
break;
}
// case eVerticalAlign.Middle:
// {
// contentRect.Y=boundingRectangle.Y+(boundingRectangle.Height-contentRect.Height)/2;
// break;
// }
}
return contentRect;
}
private eHorizontalAlign GetHorizontalAlign(eCellPartAlignment align, bool leftToRight)
{
if(((align==eCellPartAlignment.NearBottom || align==eCellPartAlignment.NearCenter ||
align==eCellPartAlignment.NearTop) && leftToRight) ||
((align==eCellPartAlignment.FarBottom || align==eCellPartAlignment.FarCenter ||
align==eCellPartAlignment.FarTop) && !leftToRight))
return eHorizontalAlign.Left;
else if(align==eCellPartAlignment.CenterBottom || align==eCellPartAlignment.CenterTop)
return eHorizontalAlign.Center;
return eHorizontalAlign.Right;
}
private eVerticalAlign GetVerticalAlign(eCellPartAlignment align)
{
eVerticalAlign va=eVerticalAlign.Middle;
switch(align)
{
case eCellPartAlignment.FarBottom:
case eCellPartAlignment.NearBottom:
case eCellPartAlignment.CenterBottom:
va=eVerticalAlign.Bottom;
break;
case eCellPartAlignment.FarTop:
case eCellPartAlignment.NearTop:
case eCellPartAlignment.CenterTop:
va=eVerticalAlign.Top;
break;
}
return va;
}
private System.Drawing.Size CheckBoxSize
{
get
{
return new Size(Dpi.Width12,Dpi.Height12);
}
}
/// <summary>
/// Returns spacing between check box and image if both are displayed
/// </summary>
private int ImageCheckBoxSpacing
{
get {return Dpi.Width1;}
}
/// <summary>
/// Returns spacing between image or checkbox and text
/// </summary>
private int ImageTextSpacing
{
get {return Dpi.Width1;}
}
/// <summary>
/// Returns horizontal spacing between cells in a node
/// </summary>
public int CellHorizontalSpacing
{
get {return Dpi.Width1;}
}
/// <summary>
/// Returns vertical spacing between cells in a node
/// </summary>
public int CellVerticalSpacing
{
get { return Dpi.Height1; }
}
/// <summary>
/// Spacing between different parts of the cell, like image, option button, text and expand button area
/// </summary>
public int CellPartSpacing
{
get { return Dpi.Width1; }
}
public Size LayoutCells(NodeLayoutContextInfo layoutInfo, int x, int y)
{
eCellLayout layout=layoutInfo.CellLayout;
if(layoutInfo.ContextNode.CellLayout!=layoutInfo.CellLayout && layoutInfo.ContextNode.CellLayout!=eCellLayout.Default)
layout=layoutInfo.ContextNode.CellLayout;
if(layout==eCellLayout.Horizontal || layout==eCellLayout.Default)
return this.LayoutCellsHorizontal(layoutInfo,x,y);
else
return this.LayoutCellsVertical(layoutInfo,x,y);
}
private Size LayoutCellsHorizontal(NodeLayoutContextInfo layoutInfo, int x, int y)
{
Node node=layoutInfo.ContextNode;
int height=0, width=0;
for(int i=0;i<node.Cells.Count;i++)
{
Cell cell=node.Cells[i];
bool bCellVisible=true;
// Setup cell layout helper class
LayoutCellInfo cellLayout=this.GetLayoutCellInfo();
cellLayout.Top=y;
cellLayout.Left=x;
cellLayout.CellWidth=0;
cellLayout.ContextCell=cell;
cellLayout.Graphics=layoutInfo.Graphics;
cellLayout.LeftToRight=layoutInfo.LeftToRight;
cellLayout.Font=layoutInfo.DefaultFont;
if(cell.Layout!=eCellPartLayout.Default)
cellLayout.VerticalPartAlignment=(cell.Layout==eCellPartLayout.Vertical);
else if(layoutInfo.CellPartLayout!=eCellPartLayout.Default)
cellLayout.VerticalPartAlignment=(layoutInfo.CellPartLayout==eCellPartLayout.Vertical);
if(layoutInfo.DefaultColumns.Count>0 || layoutInfo.ChildColumns!=null && layoutInfo.ChildColumns.Count>0)
{
ColumnInfo ci=null;
if(layoutInfo.ChildColumns!=null && layoutInfo.ChildColumns.Count>0)
ci=layoutInfo.ChildColumns[i] as ColumnInfo;
else
ci=layoutInfo.DefaultColumns[i] as ColumnInfo;
bCellVisible=ci.Visible;
cellLayout.CellWidth=ci.Width;
}
// Prepare union style
if(cell.StyleNormal!=null)
cellLayout.LayoutStyle=cell.StyleNormal;
else
{
if(layoutInfo.ContextNode.Style!=null)
{
ElementStyle styleCopy = layoutInfo.DefaultCellStyle.Copy();
styleCopy.ApplyStyle(layoutInfo.ContextNode.Style);
cellLayout.LayoutStyle = styleCopy;
}
else
cellLayout.LayoutStyle=layoutInfo.DefaultCellStyle;
}
this.LayoutSingleCell(cellLayout);
if(bCellVisible)
{
x+=cell.BoundsRelative.Width;
width+=cell.BoundsRelative.Width;
if(cell.BoundsRelative.Width>0)
{
x+=this.CellHorizontalSpacing;
width+=this.CellHorizontalSpacing;
}
if(cell.BoundsRelative.Height>height)
height=cell.BoundsRelative.Height;
}
}
// Take last added spacing off
x-=this.CellHorizontalSpacing;
width-=this.CellHorizontalSpacing;
return new Size(width,height);
}
private Size LayoutCellsVertical(NodeLayoutContextInfo layoutInfo, int x, int y)
{
Node node=layoutInfo.ContextNode;
int height=0, width=0;
eHorizontalAlign align=eHorizontalAlign.Center;
int iVisibleCells=0;
for(int i=0;i<node.Cells.Count;i++)
{
Cell cell=node.Cells[i];
bool bCellVisible=true;
// Setup cell layout helper class
LayoutCellInfo cellLayout=this.GetLayoutCellInfo();
cellLayout.Top=y;
cellLayout.Left=x;
cellLayout.CellWidth=0;
cellLayout.ContextCell=cell;
cellLayout.Graphics=layoutInfo.Graphics;
cellLayout.LeftToRight=layoutInfo.LeftToRight;
cellLayout.Font=layoutInfo.DefaultFont;
if(cell.Layout!=eCellPartLayout.Default)
cellLayout.VerticalPartAlignment=(cell.Layout==eCellPartLayout.Vertical);
else if(layoutInfo.CellPartLayout!=eCellPartLayout.Default)
cellLayout.VerticalPartAlignment=(layoutInfo.CellPartLayout==eCellPartLayout.Vertical);
if(layoutInfo.DefaultColumns.Count>0 || layoutInfo.ChildColumns!=null && layoutInfo.ChildColumns.Count>0)
{
ColumnInfo ci=null;
if(layoutInfo.ChildColumns!=null && layoutInfo.ChildColumns.Count>0)
ci=layoutInfo.ChildColumns[i] as ColumnInfo;
else
ci=layoutInfo.DefaultColumns[i] as ColumnInfo;
bCellVisible=ci.Visible;
cellLayout.CellWidth=ci.Width;
}
// Prepare union style
if(cell.StyleNormal!=null)
cellLayout.LayoutStyle=cell.StyleNormal;
else
cellLayout.LayoutStyle=layoutInfo.DefaultCellStyle;
this.LayoutSingleCell(cellLayout);
cell.SetVisible(bCellVisible);
if(bCellVisible)
{
iVisibleCells++;
y+=cell.BoundsRelative.Height;
height+=cell.BoundsRelative.Height;
if(cell.BoundsRelative.Height>0)
{
y+=this.CellVerticalSpacing;
height+=this.CellVerticalSpacing;
}
if(cell.BoundsRelative.Width>width)
width=cell.BoundsRelative.Width;
}
}
// Take last added spacing off
y-=this.CellVerticalSpacing;
height-=this.CellVerticalSpacing;
// Additional pass needed if horizontal alignment is other than left and there is more than one cell visible
if(align!=eHorizontalAlign.Left && iVisibleCells>1)
{
foreach(Cell cell in node.Cells)
{
if(!cell.IsVisible)
continue;
if(align==eHorizontalAlign.Center)
this.Offset(cell,(width-cell.BoundsRelative.Width)/2,0);
else // Right aligned cells
this.Offset(cell,width-cell.BoundsRelative.Width,0);
}
}
return new Size(width,height);
}
private LayoutCellInfo m_LayoutCellInfo=null;
private LayoutCellInfo GetLayoutCellInfo()
{
if(m_LayoutCellInfo==null)
m_LayoutCellInfo=new LayoutCellInfo();
return m_LayoutCellInfo;
}
}
}
internal class LayoutCellInfo
{
public Cell ContextCell=null;
public int CellWidth=0;
public System.Drawing.Graphics Graphics=null;
public System.Drawing.Font Font=null;
public int Left=0;
public int Top=0;
public ElementStyle LayoutStyle=null;
public bool LeftToRight=true;
public bool VerticalPartAlignment=false;
public LayoutCellInfo()
{
}
}
internal class ColumnInfo
{
public bool Visible;
public int Width;
public ColumnInfo(int width, bool visible)
{
this.Width=width;
this.Visible=visible;
}
}
}

View File

@@ -0,0 +1,335 @@
using System;
using System.Collections;
using System.Drawing;
namespace DevComponents.Tree.Layout
{
/// <summary>
/// Represents the class that performs node diagram layout.
/// </summary>
internal class NodeDiagramLayout:NodeLayout
{
private eDiagramFlow m_DiagramFlow=eDiagramFlow.LeftToRight;
public NodeDiagramLayout(TreeGX treeControl, Rectangle clientArea):base(treeControl,clientArea)
{
}
public override void PerformLayout()
{
this.PrepareStyles();
// Get default Columns
ArrayList defaultColInfoList=this.GetDefaultColumnInfo();
if(m_Tree.Nodes.Count==0)
return;
System.Drawing.Graphics graphics=this.GetGraphics();
try
{
// Loop through each top-level node
Node[] topLevelNodes=this.GetTopLevelNodes();
NodeLayoutContextInfo layoutInfo=this.GetDefaultNodeLayoutContextInfo(graphics);
foreach(Node childNode in topLevelNodes)
{
if(!childNode.Visible)
continue;
layoutInfo.ContextNode=childNode;
ProcessRootNode(layoutInfo);
break;
}
EmptyBoundsUnusedNodes(topLevelNodes);
}
finally
{
if(this.DisposeGraphics)
graphics.Dispose();
}
}
private void ProcessRootNode(NodeLayoutContextInfo layoutInfo)
{
if(m_DiagramFlow==eDiagramFlow.RightToLeft || m_DiagramFlow==eDiagramFlow.BottomToTop)
layoutInfo.MapPositionNear=true;
ProcessSubNode(layoutInfo);
PositionRootNode(layoutInfo);
}
private void PositionRootNode(NodeLayoutContextInfo layoutInfo)
{
Point location=Point.Empty;
Node root=layoutInfo.ContextNode;
switch(m_DiagramFlow)
{
case eDiagramFlow.LeftToRight:
{
location.Y=(root.ChildNodesBounds.Height-root.BoundsRelative.Height)/2;
break;
}
case eDiagramFlow.RightToLeft:
{
location.X=root.ChildNodesBounds.Width+this.NodeHorizontalSpacing;
location.Y=(root.ChildNodesBounds.Height-root.BoundsRelative.Height)/2;
break;
}
case eDiagramFlow.TopToBottom:
{
location.X=0; //(root.ChildNodesBounds.Width-root.Bounds.Width)/2;
break;
}
case eDiagramFlow.BottomToTop:
{
location.X=root.ChildNodesBounds.Width; //-root.Bounds.Width; //-root.Bounds.Width)/2;
location.Y=root.ChildNodesBounds.Height+this.NodeVerticalSpacing; //-root.Bounds.Height; //+this.NodeVerticalSpacing;
break;
}
}
OffsetNodeLocation(root,location.X,location.Y);
Rectangle area=Rectangle.Empty;
area=Rectangle.Union(area,root.BoundsRelative);
PositionSubNodes(root);
area=Rectangle.Union(area,root.ChildNodesBounds);
root.ChildNodesBounds=area;
m_Width=area.Width;
m_Height=area.Height;
}
// private int GetMaxChildNodeWidth(Node parent)
// {
// int width=0;
// foreach(Node node in parent.Nodes)
// {
// if(node.Bounds.Width>width)
// width=node.Bounds.Width;
// }
// return width;
// }
private void PositionSubNodes(Node parentNode)
{
if(parentNode.Nodes.Count==0)
return;
Rectangle rChildBounds=Rectangle.Empty;
bool bFirst=true;
bool rootNode=IsRootNode(parentNode);
if(m_DiagramFlow==eDiagramFlow.LeftToRight || !rootNode && m_DiagramFlow==eDiagramFlow.TopToBottom)
{
int y=parentNode.BoundsRelative.Y-(parentNode.ChildNodesBounds.Height-parentNode.BoundsRelative.Height)/2;
int x=0;
// if(parentNode.Parent!=null)
// x=parentNode.Bounds.X+GetMaxChildNodeWidth(parentNode.Parent)+this.NodeHorizontalSpacing;
// else
x=parentNode.BoundsRelative.Right+this.NodeHorizontalSpacing;
foreach(Node node in parentNode.Nodes)
{
if(!node.Visible)
continue;
int top=y;
bool anyVisibleNodes=node.AnyVisibleNodes;
if(node.ChildNodesBounds.Height>node.BoundsRelative.Height && node.Expanded && anyVisibleNodes)
top+=(node.ChildNodesBounds.Height-node.BoundsRelative.Height)/2;
OffsetNodeLocation(node,x,top);
if(node.Expanded && anyVisibleNodes)
{
PositionSubNodes(node);
y+=(Math.Max(node.BoundsRelative.Height,node.ChildNodesBounds.Height)+this.NodeVerticalSpacing);
}
else y+=(node.BoundsRelative.Height+this.NodeVerticalSpacing);
if(bFirst)
{
rChildBounds=node.BoundsRelative;
bFirst=false;
}
else
rChildBounds=Rectangle.Union(rChildBounds,node.BoundsRelative);
if(!node.ChildNodesBounds.IsEmpty)
rChildBounds=Rectangle.Union(rChildBounds,node.ChildNodesBounds);
}
}
else if(m_DiagramFlow==eDiagramFlow.RightToLeft || !rootNode && m_DiagramFlow==eDiagramFlow.BottomToTop)
{
int y=parentNode.BoundsRelative.Y-(parentNode.ChildNodesBounds.Height-parentNode.BoundsRelative.Height)/2;
int x=parentNode.BoundsRelative.X-this.NodeHorizontalSpacing;
foreach(Node node in parentNode.Nodes)
{
if(!node.Visible)
continue;
int left=x-node.BoundsRelative.Width;
int top=y;
bool anyVisibleNodes=node.AnyVisibleNodes;
if(node.ChildNodesBounds.Height>node.BoundsRelative.Height && node.Expanded && anyVisibleNodes)
top+=(node.ChildNodesBounds.Height-node.BoundsRelative.Height)/2;
OffsetNodeLocation(node,left,top);
if(node.Expanded && anyVisibleNodes)
{
PositionSubNodes(node);
y+=(Math.Max(node.BoundsRelative.Height,node.ChildNodesBounds.Height)+this.NodeVerticalSpacing);
}
else y+=(node.BoundsRelative.Height+this.NodeVerticalSpacing);
if(bFirst)
{
rChildBounds=node.BoundsRelative;
bFirst=false;
}
else
rChildBounds=Rectangle.Union(rChildBounds,node.BoundsRelative);
if(!node.ChildNodesBounds.IsEmpty)
rChildBounds=Rectangle.Union(rChildBounds,node.ChildNodesBounds);
}
}
else if(m_DiagramFlow==eDiagramFlow.TopToBottom)
{
int y=parentNode.BoundsRelative.Bottom+this.NodeVerticalSpacing;
foreach(Node node in parentNode.Nodes)
{
if(!node.Visible)
continue;
int left=parentNode.BoundsRelative.Right+this.NodeHorizontalSpacing;
int top=y;
bool anyVisibleNodes=node.AnyVisibleNodes;
if(node.ChildNodesBounds.Height>node.BoundsRelative.Height && node.Expanded && anyVisibleNodes)
top+=(node.ChildNodesBounds.Height-node.BoundsRelative.Height)/2;
OffsetNodeLocation(node,left,top);
if(node.Expanded && anyVisibleNodes)
{
PositionSubNodes(node);
y+=(Math.Max(node.BoundsRelative.Height,node.ChildNodesBounds.Height)+this.NodeVerticalSpacing);
}
else y+=(node.BoundsRelative.Height+this.NodeVerticalSpacing);
if(bFirst)
{
rChildBounds=node.BoundsRelative;
bFirst=false;
}
else
rChildBounds=Rectangle.Union(rChildBounds,node.BoundsRelative);
if(!node.ChildNodesBounds.IsEmpty)
rChildBounds=Rectangle.Union(rChildBounds,node.ChildNodesBounds);
}
}
else if(m_DiagramFlow==eDiagramFlow.BottomToTop)
{
int y=parentNode.BoundsRelative.Top-this.NodeVerticalSpacing;
foreach(Node node in parentNode.Nodes)
{
if(!node.Visible)
continue;
int left=parentNode.BoundsRelative.Left-this.NodeHorizontalSpacing-node.BoundsRelative.Width;
int top=y-node.BoundsRelative.Height;
bool anyVisibleNodes=node.AnyVisibleNodes;
if(node.ChildNodesBounds.Height>node.BoundsRelative.Height && node.Expanded && anyVisibleNodes)
top-=(node.ChildNodesBounds.Height-node.BoundsRelative.Height)/2;
OffsetNodeLocation(node,left,top);
if(node.Expanded && anyVisibleNodes)
{
PositionSubNodes(node);
y-=(Math.Max(node.BoundsRelative.Height,node.ChildNodesBounds.Height)+this.NodeVerticalSpacing);
}
else y-=(node.BoundsRelative.Height+this.NodeVerticalSpacing);
if(bFirst)
{
rChildBounds=node.BoundsRelative;
bFirst=false;
}
else
rChildBounds=Rectangle.Union(rChildBounds,node.BoundsRelative);
if(!node.ChildNodesBounds.IsEmpty)
rChildBounds=Rectangle.Union(rChildBounds,node.ChildNodesBounds);
}
}
parentNode.ChildNodesBounds=rChildBounds;
}
private void ProcessSubNode(NodeLayoutContextInfo layoutInfo)
{
Node node=layoutInfo.ContextNode;
bool bHorizontalFlow=true;//(m_DiagramFlow==eDiagramFlow.LeftToRight || m_DiagramFlow==eDiagramFlow.RightToLeft);
if(node.SizeChanged)
{
// Calculate size of the node itself...
LayoutNode(layoutInfo);
}
else
node.SetBounds(new Rectangle(Point.Empty,node.BoundsRelative.Size));
if(node.Expanded)
{
ArrayList parentColumns=layoutInfo.ChildColumns;
ArrayList childColumns=GetNodeColumnInfo(node);
Rectangle childNodesBounds=Rectangle.Empty;
foreach(Node childNode in node.Nodes)
{
if(!childNode.Visible)
continue;
layoutInfo.ContextNode=childNode;
layoutInfo.ChildColumns=childColumns;
ProcessSubNode(layoutInfo);
if(bHorizontalFlow)
{
childNodesBounds.Height+=(Math.Max(childNode.BoundsRelative.Height,childNode.ChildNodesBounds.Height)+this.NodeVerticalSpacing);
childNodesBounds.Width=Math.Max(childNodesBounds.Width,childNode.BoundsRelative.Width+(childNode.ChildNodesBounds.Width>0?this.NodeHorizontalSpacing+childNode.ChildNodesBounds.Width:0));
}
else
{
childNodesBounds.Width+=(Math.Max(childNode.BoundsRelative.Width,childNode.ChildNodesBounds.Width)+this.NodeHorizontalSpacing);
childNodesBounds.Height=Math.Max(childNodesBounds.Height,childNode.BoundsRelative.Height+(childNode.ChildNodesBounds.Height>0?this.NodeVerticalSpacing+childNode.ChildNodesBounds.Height:0));
}
}
layoutInfo.ChildColumns=parentColumns;
if(bHorizontalFlow)
{
if(childNodesBounds.Height>0)
childNodesBounds.Height-=this.NodeVerticalSpacing;
}
else
{
if(childNodesBounds.Width>0)
childNodesBounds.Width-=this.NodeHorizontalSpacing;
}
node.ChildNodesBounds=childNodesBounds;
layoutInfo.ChildColumns=null;
layoutInfo.ContextNode=node;
}
else node.ChildNodesBounds=Rectangle.Empty;
}
/// <summary>
/// Returns true if root node should have expanded part
/// </summary>
protected override bool RootHasExpandedPart
{
get {return false;}
}
/// <summary>
/// Indicates the layout flow for the nodes.
/// </summary>
public eDiagramFlow DiagramFlow
{
get {return m_DiagramFlow;}
set
{
m_DiagramFlow=value;
}
}
}
}

View File

@@ -0,0 +1,591 @@
using System;
using System.Drawing;
using System.Collections;
namespace DevComponents.Tree.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 TreeGX m_Tree=null;
protected Rectangle m_ClientArea;
//protected int m_ExpandAreaWidth=8;
private Size m_ExpandPartSize = new Size(9, 9);
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=0;
private int m_NodeHorizontalSpacing=0;
private CellLayout m_CellLayout=null;
private Graphics m_Graphics=null;
#endregion
public NodeLayout(TreeGX treeControl, Rectangle clientArea)
{
m_Tree=treeControl;
m_ClientArea=clientArea;
}
/// <summary>
/// Performs layout of the nodes inside of the tree control.
/// </summary>
public virtual void PerformLayout()
{
}
/// <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 graphics=this.GetGraphics();
try
{
NodeLayoutContextInfo layoutInfo=this.GetDefaultNodeLayoutContextInfo(graphics);
layoutInfo.ContextNode=node;
LayoutNode(layoutInfo);
}
finally
{
graphics.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();
if(m_Tree.AntiAlias)
{
g.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
}
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);
}
}
/// <summary>
/// Returns default top-level columns for tree control.
/// </summary>
/// <returns>Returns array list of ColumnInfo objects.</returns>
protected virtual ArrayList GetDefaultColumnInfo()
{
ArrayList ci=new ArrayList();
ColumnHeaderCollection columns=m_Tree.Columns;
if(columns!=null)
{
foreach(ColumnHeader h in columns)
{
ci.Add(new ColumnInfo(h.Bounds.Width, h.Visible));
}
}
return ci;
}
/// <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 ArrayList GetNodeColumnInfo(Node node)
{
if(node.NodesColumns.Count==0)
return null;
ArrayList ci=new ArrayList();
foreach(ColumnHeader h in node.NodesColumns)
{
ci.Add(new ColumnInfo(h.Width.Absolute, h.Visible));
}
return ci;
}
/// <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;
}
/// <summary>
/// Returns width of the expand button area. Default is 8 pixels.
/// </summary>
protected virtual int ExpandAreaWidth
{
get {return Dpi.Width(m_ExpandPartSize.Width);}
}
/// <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.CommandAreaWidth-
ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Right),layoutInfo.ContextNode.ContentBounds.Y+
ElementStyleLayout.StyleSpacing(nodeStyle,eSpacePart.Border,eStyleSide.Top),
this.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)
{
Node node=layoutInfo.ContextNode;
Size partSize=Dpi.Size(GetExpandPartSize());
Rectangle bounds=new Rectangle(0,0,partSize.Width,partSize.Height);
bounds.Y=(node.BoundsRelative.Height-bounds.Height)/2;
if(bLeftNode)
bounds.X=(this.ExpandAreaWidth-bounds.Width)/2;
else
bounds.X=node.BoundsRelative.Right-this.ExpandAreaWidth+(this.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 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)
{
// if(!layoutInfo.ContextNode.SizeChanged)
// return;
bool bHasExpandPart=this.HasExpandPart(layoutInfo);
bool bHasCommandPart=this.HasCommandPart(layoutInfo);
Node node=layoutInfo.ContextNode;
Rectangle nodeRect=Rectangle.Empty;
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.MapPositionNear && layoutInfo.LeftToRight);
if(bLeftNode && bHasExpandPart || this.ReserveExpandPartSpace)
{
width+=(this.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); // nodeStyle.MarginLeft+nodeStyle.PaddingLeft;
y+=ElementStyleLayout.TopWhiteSpace(nodeStyle); //nodeStyle.MarginTop+nodeStyle.PaddingTop;
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)
width+=this.ExpandAreaWidth;
if(bHasCommandPart)
{
width+=this.CommandAreaWidth;
nodeContentRect.Width+=this.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)
LayoutExpandPart(layoutInfo,bLeftNode);
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 virtual CellLayout GetCellLayout()
{
if(m_CellLayout==null)
m_CellLayout=new CellLayout();
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.Left=0;
layoutInfo.Top=0; // TODO: Include Columns if visible into this...
layoutInfo.DefaultFont=m_Tree.Font;
layoutInfo.LeftToRight=(this.LeftRight==System.Windows.Forms.LeftRightAlignment.Left);
layoutInfo.Graphics=graphics;
layoutInfo.Styles=m_Tree.Styles;
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;
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);
}
}
}
#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.NodesColumns.Count==0)
{
node.ColumnHeaderHeight=0;
return;
}
int x=layoutInfo.Left;
int y=layoutInfo.ContextNode.BoundsRelative.Bottom;
bool bLeftNode=(layoutInfo.MapPositionNear && layoutInfo.LeftToRight);
int expandPartWidth=this.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().CellHorizontalSpacing);
}
#endregion
#region RTL Support
public virtual System.Windows.Forms.LeftRightAlignment LeftRight
{
get {return m_LeftRight;}
set {m_LeftRight=value;}
}
#endregion
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Drawing;
using System.Collections;
namespace DevComponents.Tree.Layout
{
/// <summary>
/// Used to pass node contextual information used for layout of the node.
/// </summary>
internal class NodeLayoutContextInfo
{
public Node ContextNode=null;
public Rectangle ClientRectangle=Rectangle.Empty;
public int Left;
public int Top;
public ArrayList DefaultColumns=null;
public ArrayList ChildColumns=null;
public Font DefaultFont=null;
public ElementStyle DefaultCellStyle=null;
public ElementStyle DefaultNodeStyle=null;
public Size DefaultHeaderSize=Size.Empty;
public bool LeftToRight=true;
public bool HasExpandPart=true;
public System.Drawing.Graphics Graphics=null;
public ElementStyleCollection Styles=null;
public eCellLayout CellLayout=eCellLayout.Horizontal;
public eCellPartLayout CellPartLayout=eCellPartLayout.Horizontal;
public bool MapPositionNear=false;
}
}

View File

@@ -0,0 +1,61 @@
using System;
using System.Drawing;
using System.Collections;
namespace DevComponents.Tree.Layout
{
/// <summary>
/// Internal class that orders one level of the nodes in list like layout. Nodes are ordered from top to bottom.
/// </summary>
internal class NodeListLayout:Layout.NodeLayout
{
public NodeListLayout(TreeGX treeControl, Rectangle clientArea):base(treeControl,clientArea)
{
}
public override void PerformLayout()
{
if(m_Tree.Nodes.Count==0)
return;
this.PrepareStyles();
System.Drawing.Graphics graphics=this.GetGraphics();
m_Width=0;
m_Height=0;
try
{
NodeCollection nodes=this.GetLayoutNodes();
NodeLayoutContextInfo layoutInfo=this.GetDefaultNodeLayoutContextInfo(graphics);
foreach(Node childNode in nodes)
{
if(!childNode.Visible)
continue;
layoutInfo.ContextNode=childNode;
ProcessNode(layoutInfo);
if(childNode.BoundsRelative.Width>this.Width)
m_Width=childNode.BoundsRelative.Width;
}
m_Height=layoutInfo.Top-this.NodeVerticalSpacing;
}
finally
{
if(this.DisposeGraphics)
graphics.Dispose();
}
}
private void ProcessNode(NodeLayoutContextInfo layoutInfo)
{
LayoutNode(layoutInfo);
layoutInfo.ContextNode.SetBounds(new Rectangle(layoutInfo.Left,layoutInfo.Top,layoutInfo.ContextNode.BoundsRelative.Width,layoutInfo.ContextNode.BoundsRelative.Height));
//OffsetNodeLocation(layoutInfo.ContextNode,layoutInfo.Left,layoutInfo.Top);
layoutInfo.Top+=(layoutInfo.ContextNode.BoundsRelative.Height+this.NodeVerticalSpacing);
}
private NodeCollection GetLayoutNodes()
{
return m_Tree.Nodes;
}
}
}

View File

@@ -0,0 +1,525 @@
using System;
using System.Drawing;
using System.Collections;
namespace DevComponents.Tree.Layout
{
/// <summary>
/// Represents the class that performs node map layout.
/// </summary>
internal class NodeMapLayout:NodeLayout
{
#region Private Variables
private eMapFlow m_MapFlow=eMapFlow.Spread;
#endregion
public NodeMapLayout(TreeGX treeControl, Rectangle clientArea):base(treeControl,clientArea)
{
}
public override void PerformLayout()
{
this.PrepareStyles();
// Get default Columns
//ArrayList defaultColInfoList=this.GetDefaultColumnInfo();
if(m_Tree.Nodes.Count==0)
return;
Graphics graphics=this.GetGraphics();
try
{
// Loop through each top-level node
Node[] topLevelNodes=this.GetTopLevelNodes();
NodeLayoutContextInfo layoutInfo=this.GetDefaultNodeLayoutContextInfo(graphics);
foreach(Node childNode in topLevelNodes)
{
if(!childNode.Visible)
continue;
layoutInfo.ContextNode=childNode;
ProcessRootNode(layoutInfo);
break;
}
EmptyBoundsUnusedNodes(topLevelNodes);
}
finally
{
if(this.DisposeGraphics)
graphics.Dispose();
}
}
private void ProcessRootNode(NodeLayoutContextInfo layoutInfo)
{
Node node=layoutInfo.ContextNode;
// Center root node on the screen
//if(node.SizeChanged)
//{
// Calculate size of the node itself...
LayoutNode(layoutInfo);
// Calculate size and location of node column header if any
// if(node.NodesColumnHeaderVisible)
// {
// LayoutColumnHeader(layoutInfo);
// }
//}
// if(node.Expanded && node.NodesColumnHeaderVisible && node.NodesColumns.Count>0)
// layoutInfo.Top+=node.ColumnHeaderHeight;
NodesMapPosition positions=NodesMapPosition.Empty;
bool bNear=false;
if(node.Expanded)
{
if(node.NodesColumns.Count>0)
layoutInfo.ChildColumns=GetNodeColumnInfo(node);
foreach(Node childNode in node.Nodes)
{
if(!childNode.Visible)
continue;
layoutInfo.ContextNode=childNode;
if(bNear || childNode.MapSubRootPosition==eMapPosition.Near)
{
layoutInfo.MapPositionNear=true;
ProcessSubNode(layoutInfo);
positions.Near.Add(childNode);
positions.NearHeight+=GetTotalChildNodeHeight(childNode);
bNear=true;
}
else if(childNode.MapSubRootPosition==eMapPosition.Far)
{
layoutInfo.MapPositionNear=false;
ProcessSubNode(layoutInfo);
positions.Far.Add(childNode);
positions.FarHeight+=GetTotalChildNodeHeight(childNode);
}
else
positions.Default.Add(childNode);
}
// Assign nodes to appropriate sides....
if(positions.Default.Count>0)
{
int toFar=0;
if(positions.Near.Count==0 && positions.Far.Count==0 && positions.Default.Count<=4)
toFar=2;
else
toFar=(int)Math.Ceiling((double)((positions.Near.Count-positions.Far.Count+positions.Default.Count))/2);
for(int i=0;i<toFar;i++)
{
layoutInfo.ContextNode=positions.Default[0] as Node;
if(m_MapFlow==eMapFlow.RightToLeft)
layoutInfo.MapPositionNear=true;
else
layoutInfo.MapPositionNear=false;
ProcessSubNode(layoutInfo);
positions.Far.Add(positions.Default[0]);
positions.FarHeight+=GetTotalChildNodeHeight(positions.Default[0] as Node);
positions.Default.RemoveAt(0);
if(positions.Default.Count==0)
break;
}
for(int i=0;i<positions.Default.Count;i++)
{
layoutInfo.ContextNode=positions.Default[i] as Node;
if(m_MapFlow==eMapFlow.LeftToRight)
layoutInfo.MapPositionNear=false;
else
layoutInfo.MapPositionNear=true;
ProcessSubNode(layoutInfo);
positions.Near.Add(positions.Default[i]);
positions.NearHeight+=GetTotalChildNodeHeight(positions.Default[i] as Node); //+this.NodeVerticalSpacing;
}
positions.Default.Clear();
}
layoutInfo.ChildColumns=null;
layoutInfo.ContextNode=node;
}
// Set the position of the root node
Point pRoot = new Point(0, 0);
pRoot.Offset(node.Offset,0);
// Adjust top position
node.SetBounds(new Rectangle(pRoot,node.BoundsRelative.Size));
node.ExpandPartRectangleRelative.Offset(pRoot);
foreach(Cell c in node.Cells)
c.BoundsRelative.Offset(pRoot);
// Set the position of the child nodes
if(node.Expanded)
{
PositionCenterRootSubNodes(node, positions);
}
else
{
node.ChildNodesBounds = Rectangle.Empty;
m_Width = node.Bounds.Width;
m_Height = node.Bounds.Height;
}
}
private int GetTotalChildNodeHeight(Node childNode)
{
if(childNode.Expanded)
return Math.Max(childNode.BoundsRelative.Height,childNode.ChildNodesBounds.Height);
return childNode.BoundsRelative.Height;
}
private void ProcessSubNode(NodeLayoutContextInfo layoutInfo)
{
Node node=layoutInfo.ContextNode;
//if(node.SizeChanged)
//{
// Calculate size of the node itself...
LayoutNode(layoutInfo);
//}
//else
// node.SetBounds(new Rectangle(Point.Empty,node.Bounds.Size));
if(node.Expanded && node.AnyVisibleNodes)
{
ArrayList parentColumns=layoutInfo.ChildColumns;
ArrayList childColumns=GetNodeColumnInfo(node);
if(node.NodesColumns.Count>0)
layoutInfo.ChildColumns=GetNodeColumnInfo(node);
Rectangle childNodesBounds=Rectangle.Empty;
foreach(Node childNode in node.Nodes)
{
if(!childNode.Visible)
continue;
layoutInfo.ContextNode=childNode;
layoutInfo.ChildColumns=childColumns;
ProcessSubNode(layoutInfo);
childNodesBounds.Height+=(Math.Max(childNode.BoundsRelative.Height,childNode.ChildNodesBounds.Height)+this.NodeVerticalSpacing);
childNodesBounds.Width=Math.Max(childNodesBounds.Width,childNode.BoundsRelative.Width+(childNode.ChildNodesBounds.Width>0?this.NodeHorizontalSpacing+childNode.ChildNodesBounds.Width:0));
}
layoutInfo.ChildColumns=parentColumns;
if(childNodesBounds.Height>0)
childNodesBounds.Height-=this.NodeVerticalSpacing;
node.ChildNodesBounds=childNodesBounds;
layoutInfo.ChildColumns=null;
layoutInfo.ContextNode=node;
}
else node.ChildNodesBounds=Rectangle.Empty;
}
private void PositionCenterRootSubNodes(Node root, NodesMapPosition positions)
{
Rectangle area=Rectangle.Empty;
area=Rectangle.Union(area,root.BoundsRelative);
// Far Nodes Layout
//int y=0, x=0;
int areaHeight=positions.FarHeight;
int minAreaHeight=this.GetMinimumAreaHeight(positions.Far,root.BoundsRelative.Height);
if(areaHeight<minAreaHeight)
areaHeight=minAreaHeight;
int areaLeft=root.BoundsRelative.Right-root.BoundsRelative.Width/3;
int areaTop=0;
if(m_MapFlow==eMapFlow.TopToBottom)
areaTop=root.BoundsRelative.Bottom+this.NodeVerticalSpacing; // Top Bottom Orientation
else if(m_MapFlow==eMapFlow.BottomToTop)
areaTop=root.BoundsRelative.Y-(areaHeight+this.NodeVerticalSpacing*((positions.Far.Count==1?1:positions.Far.Count-1))); //Bottom Top Orientation
else if(m_MapFlow==eMapFlow.LeftToRight || m_MapFlow==eMapFlow.RightToLeft)
areaTop=root.BoundsRelative.Y-(areaHeight+this.NodeVerticalSpacing*((positions.Far.Count==1?1:positions.Far.Count-1)));
else // Spread
areaTop=root.BoundsRelative.Y+root.BoundsRelative.Height/2-(areaHeight+this.NodeVerticalSpacing*((positions.Far.Count==1?1:positions.Far.Count-1)))/2; // Around spread orientation
if(m_MapFlow==eMapFlow.RightToLeft)
{
int areaRightMost=root.BoundsRelative.X+root.BoundsRelative.Width/3;
PositionNearSubRootNodes(root,positions.Far,areaRightMost,areaTop,areaHeight,ref area);
}
else
{
PositionFarSubRootNodes(root,positions.Far,areaLeft,areaTop,ref area);
}
if(m_MapFlow==eMapFlow.LeftToRight)
{
areaTop=root.BoundsRelative.Bottom+this.NodeVerticalSpacing;
PositionFarSubRootNodes(root,positions.Near,areaLeft,areaTop,ref area);
}
else
{
// Near nodes layout
areaHeight=positions.NearHeight;
minAreaHeight=this.GetMinimumAreaHeight(positions.Near,root.BoundsRelative.Height);
if(areaHeight<minAreaHeight)
areaHeight=minAreaHeight;
int areaRightMost=root.BoundsRelative.X+root.BoundsRelative.Width/3;
if(m_MapFlow==eMapFlow.TopToBottom)
areaTop=root.BoundsRelative.Bottom+this.NodeVerticalSpacing; // Top Bottom Orientation
else if(m_MapFlow==eMapFlow.BottomToTop)
areaTop=root.BoundsRelative.Y-(areaHeight+this.NodeVerticalSpacing*((positions.Near.Count==1?1:positions.Near.Count-1))); //Bottom Top Orientation
else if(m_MapFlow==eMapFlow.LeftToRight || m_MapFlow==eMapFlow.RightToLeft)
areaTop=root.BoundsRelative.Bottom+this.NodeVerticalSpacing; // Top Bottom Orientation
else // Spread
areaTop=root.BoundsRelative.Y+root.BoundsRelative.Height/2-(areaHeight+this.NodeVerticalSpacing*((positions.Near.Count==1?1:positions.Near.Count-1)))/2; // Around spread orientation
PositionNearSubRootNodes(root,positions.Near,areaRightMost,areaTop,areaHeight,ref area);
}
m_Width=area.Width;
m_Height=area.Height;
root.ChildNodesBounds=area;
}
private void PositionFarSubRootNodes(Node root, ArrayList farNodes, int areaLeft, int areaTop, ref Rectangle usedArea)
{
int top=areaTop;
bool twoNodesLayout = (farNodes.Count == 2);
for(int index=0;index<farNodes.Count;index++)
{
Node node=farNodes[index] as Node;
int x=areaLeft+this.NodeHorizontalSpacing;
int y=top;
if(node.ChildNodesBounds.Height>node.BoundsRelative.Height && node.Expanded && node.AnyVisibleNodes)
y+=(node.ChildNodesBounds.Height-node.BoundsRelative.Height)/2;
if(root.BoundsRelative.IntersectsWith(new Rectangle(root.BoundsRelative.X,y,node.BoundsRelative.Width,node.BoundsRelative.Height)))
{
if(twoNodesLayout && index==1)
{
y = root.BoundsRelative.Bottom + this.NodeVerticalSpacing/2;
if(node.ChildNodesBounds.Height>node.BoundsRelative.Height && node.Expanded && node.AnyVisibleNodes)
y+=(node.ChildNodesBounds.Height-node.BoundsRelative.Height)/2;
}
else
{
// Change X position since Y is already accounted for...
x+=(root.BoundsRelative.Right-x+this.NodeHorizontalSpacing);
}
}
x+=node.Offset;
OffsetNodeLocation(node,x,y);
if(node.Expanded && node.AnyVisibleNodes)
{
PositionSubNodes(node,true);
usedArea=Rectangle.Union(usedArea,node.ChildNodesBounds);
}
else
usedArea=Rectangle.Union(usedArea,node.BoundsRelative);
if(node.Expanded && node.AnyVisibleNodes)
{
top+=(Math.Max(node.ChildNodesBounds.Height,node.BoundsRelative.Height)+this.NodeVerticalSpacing);
}
else
{
top+=(node.BoundsRelative.Height+this.NodeVerticalSpacing);
}
}
}
private void PositionNearSubRootNodes(Node root, ArrayList nearNodes, int areaRightMost, int areaTop, int areaHeight, ref Rectangle usedArea)
{
int bottom=areaTop+(areaHeight+this.NodeVerticalSpacing*(nearNodes.Count-1));
bool twoNodesLayout = (nearNodes.Count == 2);
for(int index=0;index<nearNodes.Count;index++)
{
Node node=nearNodes[index] as Node;
int x=areaRightMost-node.BoundsRelative.Width-this.NodeHorizontalSpacing;
int y=0;
if(node.ChildNodesBounds.Height>node.BoundsRelative.Height && node.Expanded && node.AnyVisibleNodes)
y=bottom-((node.ChildNodesBounds.Height-node.BoundsRelative.Height)/2+node.BoundsRelative.Height);
else
y=bottom-node.BoundsRelative.Height;
// Rectangle rNodeArea=new Rectangle(x,y,node.Bounds.Width,node.Bounds.Height);
// rNodeArea.Inflate(this.NodeHorizontalSpacing,this.NodeVerticalSpacing);
//if(root.Bounds.IntersectsWith(rNodeArea))
if(root.BoundsRelative.IntersectsWith(new Rectangle(root.BoundsRelative.X,y,node.BoundsRelative.Width,node.BoundsRelative.Height)))
{
if(twoNodesLayout && index==1)
{
y = root.BoundsRelative.Top - this.NodeVerticalSpacing/2;
if(node.ChildNodesBounds.Height>node.BoundsRelative.Height && node.Expanded && node.AnyVisibleNodes)
y-=((node.ChildNodesBounds.Height-node.BoundsRelative.Height)/2+node.BoundsRelative.Height);
else
y-=node.BoundsRelative.Height;
}
else
{
// Change X position since Y is already accounted for...
x-=(x+node.BoundsRelative.Width-root.BoundsRelative.X+this.NodeHorizontalSpacing);
}
}
x-=node.Offset;
OffsetNodeLocation(node,x,y);
if(node.Expanded && node.AnyVisibleNodes)
{
PositionSubNodes(node,false);
usedArea = Rectangle.Union(usedArea, node.BoundsRelative);
usedArea=Rectangle.Union(usedArea,node.ChildNodesBounds);
}
else
usedArea=Rectangle.Union(usedArea,node.BoundsRelative);
if(node.Expanded && node.AnyVisibleNodes)
{
bottom-=(Math.Max(node.ChildNodesBounds.Height,node.BoundsRelative.Height)+this.NodeVerticalSpacing);
}
else
{
bottom-=(node.BoundsRelative.Height+this.NodeVerticalSpacing);
}
}
}
private void PositionSubNodes(Node parentNode,bool bFar)
{
if(parentNode.Nodes.Count==0)
return;
int y=parentNode.BoundsRelative.Y-(parentNode.ChildNodesBounds.Height-parentNode.BoundsRelative.Height)/2;
int x=parentNode.BoundsRelative.Right+this.SubNodeHorizontalSpacing;
if(!bFar)
{
x=parentNode.BoundsRelative.X-this.SubNodeHorizontalSpacing;
}
Rectangle rChildBounds=Rectangle.Empty;
bool bFirst=true;
if(bFar)
{
foreach(Node node in parentNode.Nodes)
{
if(!node.Visible)
continue;
int top=y;
bool anyVisibleNodes=node.AnyVisibleNodes;
if(node.ChildNodesBounds.Height>node.BoundsRelative.Height && node.Expanded && anyVisibleNodes)
top+=(node.ChildNodesBounds.Height-node.BoundsRelative.Height)/2;
OffsetNodeLocation(node,x,top);
if(node.Expanded && anyVisibleNodes)
{
PositionSubNodes(node,bFar);
y+=(Math.Max(node.BoundsRelative.Height,node.ChildNodesBounds.Height)+this.NodeVerticalSpacing);
}
else y+=(node.BoundsRelative.Height+this.NodeVerticalSpacing);
if(bFirst)
{
rChildBounds=node.BoundsRelative;
bFirst=false;
}
else
rChildBounds=Rectangle.Union(rChildBounds,node.BoundsRelative);
if(!node.ChildNodesBounds.IsEmpty)
rChildBounds=Rectangle.Union(rChildBounds,node.ChildNodesBounds);
}
}
else
{
foreach(Node node in parentNode.Nodes)
{
if(!node.Visible)
continue;
int left=x-node.BoundsRelative.Width;
int top=y;
bool anyVisibleNodes=node.AnyVisibleNodes;
if(node.ChildNodesBounds.Height>node.BoundsRelative.Height && node.Expanded && anyVisibleNodes)
top+=(node.ChildNodesBounds.Height-node.BoundsRelative.Height)/2;
OffsetNodeLocation(node,left,top);
if(node.Expanded && anyVisibleNodes)
{
PositionSubNodes(node,bFar);
y+=(Math.Max(node.BoundsRelative.Height,node.ChildNodesBounds.Height)+this.NodeVerticalSpacing);
}
else y+=(node.BoundsRelative.Height+this.NodeVerticalSpacing);
if(bFirst)
{
rChildBounds=node.BoundsRelative;
bFirst=false;
}
else
rChildBounds=Rectangle.Union(rChildBounds,node.BoundsRelative);
if(!node.ChildNodesBounds.IsEmpty)
rChildBounds=Rectangle.Union(rChildBounds,node.ChildNodesBounds);
}
}
parentNode.ChildNodesBounds=rChildBounds;
}
private int GetMinimumAreaHeight(ArrayList nodes, int rootHeight)
{
int height=rootHeight;
if(nodes.Count==1)
height+=(((Node)nodes[0]).BoundsRelative.Height*2);
else if(nodes.Count>=2)
height+=(((Node)nodes[0]).BoundsRelative.Height+((Node)nodes[1]).BoundsRelative.Height);
return height;
}
private int SubNodeHorizontalSpacing
{
get {return 24;}
}
/// <summary>
/// Returns true if root node should have expanded part
/// </summary>
protected override bool RootHasExpandedPart
{
get {return false;}
}
private struct NodesMapPosition
{
public ArrayList Near;
public ArrayList Far;
public ArrayList Default;
public int NearHeight;
public int FarHeight;
public static NodesMapPosition Empty
{
get
{
NodesMapPosition m;
m.Default=new ArrayList();
m.Near=new ArrayList();
m.Far=new ArrayList();
m.NearHeight=0;
m.FarHeight=0;
return m;
}
}
}
/// <summary>
/// Gets or sets the flow of the sub-root nodes for Map layout.
/// </summary>
public eMapFlow MapFlow
{
get{return m_MapFlow;}
set{m_MapFlow=value;}
}
}
}

View File

@@ -0,0 +1,132 @@
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
namespace DevComponents.Tree.Layout
{
/// <summary>
/// Summary description for NodeTreeLayout.
/// </summary>
internal class NodeTreeLayout:NodeLayout
{
//private bool m_LayoutPerformed=false;
public NodeTreeLayout(TreeGX treeControl, Rectangle clientArea):base(treeControl,clientArea)
{
ExpandPartSize=new Size(9,9);
}
public override void PerformLayout()
{
this.PrepareStyles();
// Get default Columns
ArrayList defaultColInfoList=this.GetDefaultColumnInfo();
Graphics graphics=this.GetGraphics();
try
{
// Loop through each top-level node
Node[] topLevelNodes=this.GetTopLevelNodes();
NodeLayoutContextInfo layoutInfo=GetDefaultNodeLayoutContextInfo(graphics);
foreach(Node childNode in topLevelNodes)
{
layoutInfo.ContextNode=childNode;
ProcessNode(layoutInfo);
}
}
finally
{
if(this.DisposeGraphics)
graphics.Dispose();
}
}
#region Node routines
private void ProcessNode(NodeLayoutContextInfo layoutInfo)
{
Node node=layoutInfo.ContextNode;
if(node.SizeChanged)
{
// Calculate size of the node itself...
LayoutNode(layoutInfo);
// Calculate size and location of node column header if any
// if(node.NodesColumnHeaderVisible)
// {
// layoutInfo.Left+=this.NodeLevelOffset;
// LayoutColumnHeader(layoutInfo);
// layoutInfo.Left-=this.NodeLevelOffset;
// }
}
else if(node.BoundsRelative.Top!=layoutInfo.Top)
{
// Adjust top position
node.SetBounds(new Rectangle(node.BoundsRelative.X,layoutInfo.Top,node.BoundsRelative.Width,node.BoundsRelative.Height));
foreach(Cell c in node.Cells)
c.SetBounds(new Rectangle(c.BoundsRelative.X,layoutInfo.Top,c.BoundsRelative.Width,c.BoundsRelative.Height));
}
// Need to set the Top position properly
layoutInfo.Top+=(node.BoundsRelative.Height+this.NodeVerticalSpacing);
// if(node.Expanded && node.NodesColumnHeaderVisible && node.NodesColumns.Count>0)
// layoutInfo.Top+=node.ColumnHeaderHeight;
if(node.Expanded)
{
int originalLevelOffset=layoutInfo.Left;
layoutInfo.Left+=this.NodeLevelOffset;
ArrayList parentColumns=layoutInfo.ChildColumns;
ArrayList childColumns=GetNodeColumnInfo(node);
foreach(Node childNode in node.Nodes)
{
layoutInfo.ContextNode=childNode;
layoutInfo.ChildColumns=childColumns;
ProcessNode(layoutInfo);
}
layoutInfo.ChildColumns=parentColumns;
layoutInfo.ContextNode=node;
layoutInfo.Left=originalLevelOffset;
}
}
/// <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 override bool ReserveExpandPartSpace
{
get
{
return true;
}
}
/// <summary>
/// Gets whether the expand part of the node +/- is aligned to the left of the node in left-to-right layout.
/// </summary>
/// <param name="node">Node to get expand part alignment for</param>
/// <returns>true if node expand part is aligned to the left in left-to-right layout.</returns>
private bool ExpandPartAlignedNear(Node node)
{
return true; // If changed LayoutExpandPart needs to be updated as well
}
// private NodeCollection GetTopLevelNodes()
// {
// return m_Tree.Nodes;
// }
private int NodeLevelOffset
{
get {return 10;}
}
#endregion
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.ComponentModel;
namespace DevComponents.Tree
{
/// <summary>
/// Represents a description of linked node and any connector points that link nodes.
/// </summary>
public class LinkedNode
{
#region Private Variables
private ConnectorPointsCollection m_ConnectorPoints=null;
private Node m_Node=null;
private Node m_Parent=null;
#endregion
#region Internal Implementation
/// <summary>
/// Creates new instance of the object.
/// </summary>
public LinkedNode()
{
m_ConnectorPoints=new ConnectorPointsCollection();
}
/// <summary>
/// Creates new instance of the object.
/// </summary>
/// <param name="linkedNode">Linkded node to initialize new instace with.</param>
public LinkedNode(Node linkedNode) : this()
{
this.Node = linkedNode;
}
/// <summary>
/// Creates new instance of the object.
/// </summary>
/// <param name="linkedNode">Linkded node to initialize new instace with.</param>
/// <param name="connectorPoints">Connector points collection to initialize new instance with.</param>
public LinkedNode(Node linkedNode, ConnectorPointsCollection connectorPoints) : this()
{
this.Node = linkedNode;
if(connectorPoints!=null)
{
m_ConnectorPoints = connectorPoints;
m_ConnectorPoints.SetParentNode(m_Parent);
}
}
/// <summary>
/// Gets or sets reference to linked node.
/// </summary>
/// <remarks>
/// Linked nodes are nodes that are related to given node but do not have strict
/// parent child relationship with the node. Each linked node must be already added as
/// child node to some other node or it will not be displayed. Linked nodes are used in Map
/// and Diagram layout styles to indicates relationships between nodes. Also See TreeGX.LinkConnector property.
/// </remarks>
[Browsable(true), DefaultValue(null)]
public Node Node
{
get { return m_Node;}
set { m_Node = value;}
}
/// <summary>
/// Gets the collection of the link connector line relative points. If a node has a link to this node through LinkedNodes collection
/// this these points outline the path connector will be drawn through from this node to it's parent linked node. By default this collection is empty which indicates that
/// connector line is drawn using predefined path. Points added here are the points through which the connector line will travel to the
/// parent node. The point coordinates added to this collection are relative from the top-left corner of this node.
/// </summary>
[Browsable(true),Category("Connectors"),DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ConnectorPointsCollection ConnectorPoints
{
get {return m_ConnectorPoints;}
}
/// <summary>
/// Gets the Node this linked node description is attached to.
/// </summary>
[Browsable(false)]
public Node Parent
{
get { return m_Parent;}
}
/// <summary>
/// Sets the parent node.
/// </summary>
/// <param name="node">Reference to parent node.</param>
internal void SetParent(Node node)
{
m_Parent = node;
m_ConnectorPoints.SetParentNode(node);
}
#endregion
}
}

View File

@@ -0,0 +1,154 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
namespace DevComponents.Tree
{
/// <summary>
/// Represents collection of LinkedNode objects that describe linked node properties.
/// </summary>
public class LinkedNodesCollection:CollectionBase
{
#region Private Variables
private Node m_ParentNode=null;
#endregion
#region Internal Implementation
/// <summary>
/// Default constructor.
/// </summary>
public LinkedNodesCollection()
{
}
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Node ParentNode
{
get {return m_ParentNode;}
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">Node that is parent of this collection.</param>
internal void SetParentNode(Node parent)
{
m_ParentNode=parent;
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="p">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(LinkedNode p)
{
return List.Add(p);
}
/// <summary>
/// Adds range of objects to the array.
/// </summary>
/// <param name="ap">Array to add.</param>
public void AddRange(LinkedNode[] ap)
{
foreach(LinkedNode p in ap)
this.Add(p);
}
/// <summary>
/// Copies objects of the collection to the array.
/// </summary>
/// <returns></returns>
public LinkedNode[] ToArray()
{
LinkedNode[] ap=new LinkedNode[this.Count];
this.CopyTo(ap);
return ap;
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public LinkedNode this[int index]
{
get {return (LinkedNode)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, LinkedNode value)
{
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(LinkedNode value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(LinkedNode value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(LinkedNode value)
{
List.Remove(value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(LinkedNode[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the ColumnHeader array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(LinkedNode[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
base.OnClear();
}
#endregion
}
}

View File

@@ -0,0 +1,165 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace DevComponents.Tree
{
/// <summary>
/// Represents the connector display for map type.
/// </summary>
public class MapConnectorDisplay:NodeConnectorDisplay
{
private int m_RootNodeConnectorWidth=4;
public MapConnectorDisplay()
{
}
/// <summary>
/// Draws connector line between two nodes.
/// </summary>
/// <param name="info">Connector context information.</param>
public override void DrawConnector(NodeConnectorDisplayInfo info)
{
if(info.LineColor.IsEmpty && info.FillColor.IsEmpty)
return;
DrawCurveConnector(info);
}
private void DrawCurveConnector(NodeConnectorDisplayInfo info)
{
Point pStart=this.GetStartPoint(info);
Point pEnd=this.GetEndPoint(info);
pStart.Offset(info.Offset.X,info.Offset.Y);
pEnd.Offset(info.Offset.X,info.Offset.Y);
// Determine whether curve can be drawn
if(Math.Abs(pStart.X-pEnd.X)<=6 || Math.Abs(pStart.Y-pEnd.Y)<=10)
{
using(Pen pen=this.GetCurvePen(info))
{
info.Graphics.DrawLine(pen,pStart,pEnd);
}
}
else
{
// Create two points in between the start and end point
Point[] p=new Point[4];
int xMulti=1, yMulti=1;
// used for direction control
if(pStart.X>pEnd.X)
xMulti=-1;
if(pStart.Y>pEnd.Y)
yMulti=-1;
p[1].X=pStart.X+(int)(Math.Abs(pStart.X-pEnd.X)*.15f*xMulti);
p[1].Y=pStart.Y+(int)(Math.Abs(pStart.Y-pEnd.Y)*.15f*yMulti);
p[2].X=pStart.X+(int)(Math.Abs(pStart.X-pEnd.X)*.5f*xMulti);
p[2].Y=pEnd.Y-(int)(yMulti*(Math.Abs(pStart.Y-pEnd.Y)*.15f));
p[0]=pStart;
p[3]=pEnd;
if(info.IsRootNode && m_RootNodeConnectorWidth>1)
{
GraphicsPath path=new GraphicsPath();
path.AddCurve(p,.5f);
path.AddLine(p[0].X,p[0].Y,p[0].X+m_RootNodeConnectorWidth*xMulti,p[0].Y);
p[0].X+=(m_RootNodeConnectorWidth*xMulti);
p[1].X+=(m_RootNodeConnectorWidth*xMulti);
p[2].X+=(m_RootNodeConnectorWidth*xMulti);
p[3].Y-=yMulti;
path.AddCurve(p,.5f);
path.AddLine(p[3].X,p[3].Y,p[3].X,p[3].Y+yMulti);
path.CloseAllFigures();
using(Brush brush=this.GetCurveBrush(info))
{
info.Graphics.FillPath(brush,path);
}
}
else
{
using(Pen pen=this.GetCurvePen(info))
{
info.Graphics.DrawCurve(pen,p,.5f);
}
}
}
}
private Pen GetCurvePen(NodeConnectorDisplayInfo info)
{
return new Pen(info.LineColor,1);
}
private Brush GetCurveBrush(NodeConnectorDisplayInfo info)
{
return new SolidBrush(info.LineColor);
}
private Point GetStartPoint(NodeConnectorDisplayInfo info)
{
Point p=Point.Empty;
if(info.IsRootNode)
{
int toMidPoint=info.ToNode.Bounds.Top+info.ToNode.Bounds.Height/2;
if(info.FromNode.Bounds.Top>toMidPoint)
p=new Point(info.FromNode.Bounds.Left+info.FromNode.Bounds.Width/2,info.FromNode.Bounds.Top);
else if(info.FromNode.Bounds.Bottom<toMidPoint)
p=new Point(info.FromNode.Bounds.Left+info.FromNode.Bounds.Width/2,info.FromNode.Bounds.Bottom-1);
}
if(p.IsEmpty)
{
// To element to the Left of from node
if(this.IsOnLeftSide(info.FromNode,info.ToNode))
p=new Point(info.FromNode.Bounds.Left,info.FromNode.Bounds.Top+info.FromNode.Bounds.Height/2);
else
p=new Point(info.FromNode.Bounds.Right,info.FromNode.Bounds.Top+info.FromNode.Bounds.Height/2);
}
return p;
}
private Point GetEndPoint(NodeConnectorDisplayInfo info)
{
// If to element is to the right of the from node and has left border end point is the vertical mid-point
// If to element is to the left of the from node and has right border end point is the vertical mid-point
// If there is no border end point is text bottom
Point p=Point.Empty;
if(this.IsOnLeftSide(info.FromNode,info.ToNode))
{
// To element is to the left of from node
Rectangle r=info.ToNode.Bounds;
if(info.StyleToNode==null || !info.StyleToNode.PaintRightBorder)
r=info.ToNode.Cells[0].TextContentBounds;
p=new Point(r.Right,r.Y+r.Height/2);
}
else
{
// To element to the right of from node
Rectangle r=info.ToNode.Bounds;
if(info.StyleToNode==null || !info.StyleToNode.PaintLeftBorder)
r=info.ToNode.Cells[0].TextContentBounds;
p=new Point(r.X,r.Y+r.Height/2);
}
return p;
}
private bool IsOnLeftSide(Node source, Node target)
{
if((source.Bounds.Left+source.Bounds.Width/2)>target.Bounds.Left)
return true;
return false;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,547 @@
using System;
using System.Drawing;
namespace DevComponents.Tree
{
/// <summary>
/// Represents class for Node's cell layout.
/// </summary>
internal class CellLayout
{
public CellLayout()
{
}
/// <summary>
/// Offset cell bounds, check box bounds, image bounds and text bounds by specified offset.
/// </summary>
/// <param name="cell">Cell to offset.</param>
/// <param name="x">Horizontal offset in pixels.</param>
/// <param name="y">Vertical offset in pixels.</param>
public void Offset(Cell cell, int x, int y)
{
cell.SetBounds(new Rectangle(cell.Bounds.X+x,cell.Bounds.Y+y,cell.Bounds.Width,cell.Bounds.Height));
if(!cell.CheckBoxBounds.IsEmpty)
cell.SetCheckBoxBounds(new Rectangle(cell.CheckBoxBounds.X+x,cell.CheckBoxBounds.Y+y,cell.CheckBoxBounds.Width,cell.CheckBoxBounds.Height));
if(!cell.ImageBounds.IsEmpty)
cell.SetImageBounds(new Rectangle(cell.ImageBounds.X+x,cell.ImageBounds.Y+y,cell.ImageBounds.Width,cell.ImageBounds.Height));
if(!cell.TextContentBounds.IsEmpty)
cell.TextContentBounds=new Rectangle(cell.TextContentBounds.X+x,cell.TextContentBounds.Y+y,cell.TextContentBounds.Width,cell.TextContentBounds.Height);
}
public void LayoutSingleCell(LayoutCellInfo info)
{
SizeF textSize=SizeF.Empty;
Font font=info.Font;
int height=0;
if(info.LayoutStyle.Font!=null)
font=info.LayoutStyle.Font;
info.ContextCell.OnLayoutCell();
if(info.ContextCell.HostedControl!=null)
{
if(info.CellWidth==0)
textSize=new SizeF(info.ContextCell.HostedControl.Width,info.ContextCell.HostedControl.Height);
else
{
int availTextWidth=info.CellWidth-
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
textSize=new SizeF(availTextWidth,info.ContextCell.HostedControl.Height);
}
}
else
{
// Calculate Text Width and Height
if(info.CellWidth==0)
{
string text=info.ContextCell.Text;
if(text!="")
textSize=info.Graphics.MeasureString(text,font);
}
else
{
int availTextWidth=info.CellWidth-
ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
availTextWidth-=info.ContextCell.Images.LargestImageSize.Width;
if(info.ContextCell.CheckBoxVisible)
availTextWidth-=CheckBoxSize.Width;
int cellHeight=font.Height;
if(info.LayoutStyle.WordWrap)
{
cellHeight=info.LayoutStyle.MaximumHeight-info.LayoutStyle.MarginTop-
info.LayoutStyle.MarginBottom-info.LayoutStyle.PaddingTop-info.LayoutStyle.PaddingBottom;
if(availTextWidth>0)
{
if(cellHeight>0)
textSize=info.Graphics.MeasureString(info.ContextCell.Text,font,new SizeF(availTextWidth,cellHeight),info.LayoutStyle.StringFormat);
else
textSize=info.Graphics.MeasureString(info.ContextCell.Text,font,availTextWidth,info.LayoutStyle.StringFormat);
}
//info.ContextCell.WordWrap=true;
}
else
textSize=new SizeF(availTextWidth,cellHeight);
}
}
if(info.LayoutStyle.WordWrap)
info.ContextCell.WordWrap=true;
else
info.ContextCell.WordWrap=false;
height=(int)Math.Ceiling(textSize.Height);
if(info.VerticalPartAlignment)
{
if(info.ContextCell.Images.LargestImageSize.Height>0)
height+=info.ContextCell.Images.LargestImageSize.Height;
if(info.ContextCell.CheckBoxVisible)
height+=CheckBoxSize.Height;
}
else
{
if(info.ContextCell.Images.LargestImageSize.Height>height)
height=info.ContextCell.Images.LargestImageSize.Height;
if(info.ContextCell.CheckBoxVisible && CheckBoxSize.Height>height)
height=CheckBoxSize.Height;
}
Rectangle r=new Rectangle(info.Left+ElementStyleLayout.LeftWhiteSpace(info.LayoutStyle),
info.Top+ElementStyleLayout.TopWhiteSpace(info.LayoutStyle)
,info.CellWidth,height);
if(r.Width==0)
{
if(info.VerticalPartAlignment)
{
r.Width=(int)Math.Ceiling(textSize.Width);
if(info.ContextCell.Images.LargestImageSize.Width>r.Width)
r.Width=(info.ContextCell.Images.LargestImageSize.Width+this.ImageTextSpacing);
if(info.ContextCell.CheckBoxVisible && CheckBoxSize.Width>r.Width)
r.Width+=(CheckBoxSize.Width+this.ImageTextSpacing);
}
else
{
r.Width=(int)Math.Ceiling(textSize.Width);
if(info.ContextCell.Images.LargestImageSize.Width>0)
r.Width+=(info.ContextCell.Images.LargestImageSize.Width+this.ImageTextSpacing);
if(info.ContextCell.CheckBoxVisible)
r.Width+=(CheckBoxSize.Width+this.ImageTextSpacing);
}
}
// Now that we have cell bounds store them
Rectangle rCellBounds=new Rectangle(info.Left,info.Top,info.CellWidth,r.Height+info.LayoutStyle.MarginTop+info.LayoutStyle.MarginBottom+info.LayoutStyle.PaddingTop+info.LayoutStyle.PaddingBottom);
if(rCellBounds.Width==0)
rCellBounds.Width=r.Width+ElementStyleLayout.HorizontalStyleWhiteSpace(info.LayoutStyle);
info.ContextCell.SetBounds(rCellBounds);
// Set Position of the image
if(!info.ContextCell.Images.LargestImageSize.IsEmpty)
{
eVerticalAlign va=GetVerticalAlign(info.ContextCell.ImageAlignment);
eHorizontalAlign ha=GetHorizontalAlign(info.ContextCell.ImageAlignment,info.LeftToRight);
if(info.VerticalPartAlignment)
info.ContextCell.SetImageBounds(AlignContentVertical(info.ContextCell.Images.LargestImageSize, ref r, ha, va, this.ImageTextSpacing));
else
info.ContextCell.SetImageBounds(AlignContent(info.ContextCell.Images.LargestImageSize, ref r, ha, va, this.ImageTextSpacing));
}
else
info.ContextCell.SetImageBounds(Rectangle.Empty);
// Set position of the check box
if(info.ContextCell.CheckBoxVisible)
{
eVerticalAlign va=GetVerticalAlign(info.ContextCell.CheckBoxAlignment);
eHorizontalAlign ha=GetHorizontalAlign(info.ContextCell.CheckBoxAlignment,info.LeftToRight);
if(info.VerticalPartAlignment)
info.ContextCell.SetCheckBoxBounds(AlignContentVertical(this.CheckBoxSize, ref r, ha, va, this.ImageTextSpacing));
else
info.ContextCell.SetCheckBoxBounds(AlignContent(this.CheckBoxSize, ref r, ha, va, this.ImageTextSpacing));
}
else
info.ContextCell.SetCheckBoxBounds(Rectangle.Empty);
// Set position of the text
//info.ContextCell.SetTextBounds(Rectangle.Empty);
if(!textSize.IsEmpty)
info.ContextCell.TextContentBounds=r;
else
info.ContextCell.TextContentBounds=Rectangle.Empty;
}
private Rectangle AlignContent(System.Drawing.Size contentSize, ref Rectangle boundingRectangle, eHorizontalAlign horizAlign, eVerticalAlign vertAlign, int contentSpacing)
{
Rectangle contentRect=new Rectangle(Point.Empty,contentSize);
switch(horizAlign)
{
case eHorizontalAlign.Right:
{
contentRect.X=boundingRectangle.Right-contentRect.Width;
boundingRectangle.Width-=(contentRect.Width+contentSpacing);
break;
}
//case eHorizontalAlign.Left:
default:
{
contentRect.X=boundingRectangle.X;
boundingRectangle.X=contentRect.Right+contentSpacing;
boundingRectangle.Width-=(contentRect.Width+contentSpacing);
break;
}
// case eHorizontalAlign.Center:
// {
// contentRect.X=boundingRectangle.X+(boundingRectangle.Width-contentRect.Width)/2;
// break;
// }
}
switch(vertAlign)
{
case eVerticalAlign.Top:
{
contentRect.Y=boundingRectangle.Y;
break;
}
case eVerticalAlign.Middle:
{
contentRect.Y=boundingRectangle.Y+(boundingRectangle.Height-contentRect.Height)/2;
break;
}
case eVerticalAlign.Bottom:
{
contentRect.Y=boundingRectangle.Bottom-contentRect.Height;
break;
}
}
return contentRect;
}
private Rectangle AlignContentVertical(System.Drawing.Size contentSize, ref Rectangle boundingRectangle, eHorizontalAlign horizAlign, eVerticalAlign vertAlign, int contentSpacing)
{
Rectangle contentRect=new Rectangle(Point.Empty,contentSize);
switch(horizAlign)
{
case eHorizontalAlign.Left:
{
contentRect.X=boundingRectangle.X;
break;
}
case eHorizontalAlign.Right:
{
contentRect.X=boundingRectangle.Right-contentRect.Width;
break;
}
case eHorizontalAlign.Center:
{
contentRect.X=boundingRectangle.X+(boundingRectangle.Width-contentRect.Width)/2;
break;
}
}
switch(vertAlign)
{
case eVerticalAlign.Bottom:
{
contentRect.Y=boundingRectangle.Bottom-contentRect.Height;
boundingRectangle.Height-=(contentRect.Height+contentSpacing);
break;
}
//case eVerticalAlign.Top:
default:
{
contentRect.Y=boundingRectangle.Y;
boundingRectangle.Y=contentRect.Bottom+contentSpacing;
boundingRectangle.Height-=(contentRect.Height+contentSpacing);
break;
}
// case eVerticalAlign.Middle:
// {
// contentRect.Y=boundingRectangle.Y+(boundingRectangle.Height-contentRect.Height)/2;
// break;
// }
}
return contentRect;
}
private eHorizontalAlign GetHorizontalAlign(eCellPartAlignment align, bool leftToRight)
{
if(((align==eCellPartAlignment.NearBottom || align==eCellPartAlignment.NearCenter ||
align==eCellPartAlignment.NearTop) && leftToRight) ||
((align==eCellPartAlignment.FarBottom || align==eCellPartAlignment.FarCenter ||
align==eCellPartAlignment.FarTop) && !leftToRight))
return eHorizontalAlign.Left;
else if(align==eCellPartAlignment.CenterBottom || align==eCellPartAlignment.CenterTop)
return eHorizontalAlign.Center;
return eHorizontalAlign.Right;
}
private eVerticalAlign GetVerticalAlign(eCellPartAlignment align)
{
eVerticalAlign va=eVerticalAlign.Middle;
switch(align)
{
case eCellPartAlignment.FarBottom:
case eCellPartAlignment.NearBottom:
case eCellPartAlignment.CenterBottom:
va=eVerticalAlign.Bottom;
break;
case eCellPartAlignment.FarTop:
case eCellPartAlignment.NearTop:
case eCellPartAlignment.CenterTop:
va=eVerticalAlign.Top;
break;
}
return va;
}
private System.Drawing.Size CheckBoxSize
{
get
{
return new Size(12,12);
}
}
/// <summary>
/// Returns spacing between check box and image if both are displayed
/// </summary>
private int ImageCheckBoxSpacing
{
get {return 1;}
}
/// <summary>
/// Returns spacing between image or checkbox and text
/// </summary>
private int ImageTextSpacing
{
get {return 1;}
}
/// <summary>
/// Returns horizontal spacing between cells in a node
/// </summary>
public int CellHorizontalSpacing
{
get {return 1;}
}
/// <summary>
/// Returns vertical spacing between cells in a node
/// </summary>
public int CellVerticalSpacing
{
get {return 1;}
}
/// <summary>
/// Spacing between different parts of the cell, like image, option button, text and expand button area
/// </summary>
public int CellPartSpacing
{
get {return 1;}
}
public Size LayoutCells(NodeLayoutContextInfo layoutInfo, int x, int y)
{
eCellLayout layout=layoutInfo.CellLayout;
if(layoutInfo.ContextNode.CellLayout!=layoutInfo.CellLayout && layoutInfo.ContextNode.CellLayout!=eCellLayout.Default)
layout=layoutInfo.ContextNode.CellLayout;
if(layout==eCellLayout.Horizontal || layout==eCellLayout.Default)
return this.LayoutCellsHorizontal(layoutInfo,x,y);
else
return this.LayoutCellsVertical(layoutInfo,x,y);
}
private Size LayoutCellsHorizontal(NodeLayoutContextInfo layoutInfo, int x, int y)
{
Node node=layoutInfo.ContextNode;
int height=0, width=0;
for(int i=0;i<node.Cells.Count;i++)
{
Cell cell=node.Cells[i];
bool bCellVisible=true;
// Setup cell layout helper class
LayoutCellInfo cellLayout=this.GetLayoutCellInfo();
cellLayout.Top=y;
cellLayout.Left=x;
cellLayout.CellWidth=0;
cellLayout.ContextCell=cell;
cellLayout.Graphics=layoutInfo.Graphics;
cellLayout.LeftToRight=layoutInfo.LeftToRight;
cellLayout.Font=layoutInfo.DefaultFont;
if(cell.Layout!=eCellPartLayout.Default)
cellLayout.VerticalPartAlignment=(cell.Layout==eCellPartLayout.Vertical);
else if(layoutInfo.CellPartLayout!=eCellPartLayout.Default)
cellLayout.VerticalPartAlignment=(layoutInfo.CellPartLayout==eCellPartLayout.Vertical);
if(layoutInfo.DefaultColumns.Count>0 || layoutInfo.ChildColumns!=null && layoutInfo.ChildColumns.Count>0)
{
ColumnInfo ci=null;
if(layoutInfo.ChildColumns!=null && layoutInfo.ChildColumns.Count>0)
ci=layoutInfo.ChildColumns[i] as ColumnInfo;
else
ci=layoutInfo.DefaultColumns[i] as ColumnInfo;
bCellVisible=ci.Visible;
cellLayout.CellWidth=ci.Width;
}
// Prepare union style
if(cell.StyleNormal!=null)
cellLayout.LayoutStyle=cell.StyleNormal;
else
cellLayout.LayoutStyle=layoutInfo.DefaultCellStyle;
this.LayoutSingleCell(cellLayout);
if(bCellVisible)
{
x+=cell.Bounds.Width;
width+=cell.Bounds.Width;
if(cell.Bounds.Width>0)
{
x+=this.CellHorizontalSpacing;
width+=this.CellHorizontalSpacing;
}
if(cell.Bounds.Height>height)
height=cell.Bounds.Height;
}
}
// Take last added spacing off
x-=this.CellHorizontalSpacing;
width-=this.CellHorizontalSpacing;
return new Size(width,height);
}
private Size LayoutCellsVertical(NodeLayoutContextInfo layoutInfo, int x, int y)
{
Node node=layoutInfo.ContextNode;
int height=0, width=0;
eHorizontalAlign align=eHorizontalAlign.Center;
int iVisibleCells=0;
for(int i=0;i<node.Cells.Count;i++)
{
Cell cell=node.Cells[i];
bool bCellVisible=true;
// Setup cell layout helper class
LayoutCellInfo cellLayout=this.GetLayoutCellInfo();
cellLayout.Top=y;
cellLayout.Left=x;
cellLayout.CellWidth=0;
cellLayout.ContextCell=cell;
cellLayout.Graphics=layoutInfo.Graphics;
cellLayout.LeftToRight=layoutInfo.LeftToRight;
cellLayout.Font=layoutInfo.DefaultFont;
if(layoutInfo.DefaultColumns.Count>0 || layoutInfo.ChildColumns!=null && layoutInfo.ChildColumns.Count>0)
{
ColumnInfo ci=null;
if(layoutInfo.ChildColumns!=null && layoutInfo.ChildColumns.Count>0)
ci=layoutInfo.ChildColumns[i] as ColumnInfo;
else
ci=layoutInfo.DefaultColumns[i] as ColumnInfo;
bCellVisible=ci.Visible;
cellLayout.CellWidth=ci.Width;
}
// Prepare union style
if(cell.StyleNormal!=null)
cellLayout.LayoutStyle=cell.StyleNormal;
else
cellLayout.LayoutStyle=layoutInfo.DefaultCellStyle;
this.LayoutSingleCell(cellLayout);
cell.SetVisible(bCellVisible);
if(bCellVisible)
{
iVisibleCells++;
y+=cell.Bounds.Height;
height+=cell.Bounds.Height;
if(cell.Bounds.Height>0)
{
y+=this.CellVerticalSpacing;
height+=this.CellVerticalSpacing;
}
if(cell.Bounds.Width>width)
width=cell.Bounds.Width;
}
}
// Take last added spacing off
y-=this.CellVerticalSpacing;
height-=this.CellVerticalSpacing;
// Additional pass needed if horizontal alignment is other than left and there is more than one cell visible
if(align!=eHorizontalAlign.Left && iVisibleCells>1)
{
foreach(Cell cell in node.Cells)
{
if(!cell.IsVisible)
continue;
if(align==eHorizontalAlign.Center)
this.Offset(cell,(width-cell.Bounds.Width)/2,0);
else // Right aligned cells
this.Offset(cell,width-cell.Bounds.Width,0);
}
}
return new Size(width,height);
}
private LayoutCellInfo m_LayoutCellInfo=null;
private LayoutCellInfo GetLayoutCellInfo()
{
if(m_LayoutCellInfo==null)
m_LayoutCellInfo=new LayoutCellInfo();
return m_LayoutCellInfo;
}
}
internal class LayoutCellInfo
{
public Cell ContextCell=null;
public int CellWidth=0;
public System.Drawing.Graphics Graphics=null;
public System.Drawing.Font Font=null;
public int Left=0;
public int Top=0;
public ElementStyle LayoutStyle=null;
public bool LeftToRight=true;
public bool VerticalPartAlignment=false;
public LayoutCellInfo()
{
}
}
internal class ColumnInfo
{
public bool Visible;
public int Width;
public ColumnInfo(int width, bool visible)
{
this.Width=width;
this.Visible=visible;
}
}
}

View File

@@ -0,0 +1,300 @@
using System;
using System.Collections;
using System.ComponentModel;
namespace DevComponents.Tree
{
/// <summary>
/// Represents collection for Node objects.
/// </summary>
public class NodeCollection:CollectionBase
{
#region Private Variables
private Node m_ParentNode=null;
private TreeGX m_TreeControl=null;
private eTreeAction m_SourceAction=eTreeAction.Code;
#endregion
#region Internal Implementation
public NodeCollection()
{
}
/// <summary>
/// Gets or sets the node this collection is associated with.
/// </summary>
[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Node ParentNode
{
get {return m_ParentNode;}
}
/// <summary>
/// Sets the node collection belongs to.
/// </summary>
/// <param name="parent">Node that is parent of this collection.</param>
internal void SetParentNode(Node parent)
{
m_ParentNode=parent;
}
internal TreeGX TreeControl
{
get {return m_TreeControl;}
set {m_TreeControl=value;}
}
/// <summary>
/// Adds new object to the collection.
/// </summary>
/// <param name="node">Object to add.</param>
/// <returns>Index of newly added object.</returns>
public int Add(Node node)
{
return List.Add(node);
}
/// <summary>
/// Adds new object to the collection and provides information about the source of the command
/// </summary>
/// <param name="node">Node to add</param>
/// <param name="action">Source action</param>
/// <returns></returns>
public int Add(Node node, eTreeAction action)
{
m_SourceAction = action;
return List.Add(node);
}
/// <summary>
/// Adds an array of objects to the collection.
/// </summary>
/// <param name="nodes">Array of Node objects.</param>
public void AddRange(Node[] nodes)
{
foreach(Node node in nodes)
List.Add(node);
}
/// <summary>
/// Returns reference to the object in collection based on it's index.
/// </summary>
public Node this[int index]
{
get {return (Node)(List[index]);}
set {List[index] = value;}
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
public void Insert(int index, Node value)
{
List.Insert(index, value);
}
/// <summary>
/// Inserts new object into the collection.
/// </summary>
/// <param name="index">Position of the object.</param>
/// <param name="value">Object to insert.</param>
/// <param name="action">Action that is causing the event</param>
public void Insert(int index, Node value, eTreeAction action)
{
m_SourceAction = action;
List.Insert(index, value);
}
/// <summary>
/// Returns index of the object inside of the collection.
/// </summary>
/// <param name="value">Reference to the object.</param>
/// <returns>Index of the object.</returns>
public int IndexOf(Node value)
{
return List.IndexOf(value);
}
/// <summary>
/// Returns whether collection contains specified object.
/// </summary>
/// <param name="value">Object to look for.</param>
/// <returns>true if object is part of the collection, otherwise false.</returns>
public bool Contains(Node value)
{
return List.Contains(value);
}
/// <summary>
/// Removes specified object from the collection.
/// </summary>
/// <param name="value"></param>
public void Remove(Node value)
{
List.Remove(value);
}
/// <summary>
/// Removes specified object from the collection and provides information about source of the command
/// </summary>
/// <param name="node">Node to remove</param>
/// <param name="action">Source action</param>
public void Remove(Node node, eTreeAction action)
{
m_SourceAction = action;
List.Remove(node);
}
protected override void OnRemove(int index, object value)
{
TreeGX tree = GetTreeControl();
if(tree!=null)
tree.InvokeBeforeNodeRemove(m_SourceAction, value as Node, m_ParentNode);
base.OnRemove (index, value);
}
protected override void OnRemoveComplete(int index,object value)
{
base.OnRemoveComplete(index,value);
Node node=value as Node;
node.SetParent(null);
node.internalTreeControl=null;
if(m_ParentNode!=null) m_ParentNode.OnChildNodeRemoved(node);
TreeGX tree = GetTreeControl();
if(tree!=null)
{
tree.InvokeAfterNodeRemove(m_SourceAction, value as Node, m_ParentNode);
tree.NodeRemoved(m_SourceAction, value as Node, m_ParentNode, index);
}
}
protected override void OnInsert(int index, object value)
{
TreeGX tree = GetTreeControl();
if(tree!=null)
tree.InvokeBeforeNodeInsert(m_SourceAction, value as Node, m_ParentNode);
base.OnInsert (index, value);
}
protected override void OnInsertComplete(int index,object value)
{
base.OnInsertComplete(index,value);
Node node=value as Node;
if(m_ParentNode!=null)
{
if(node.Parent!=null && node.Parent!=m_ParentNode)
node.Remove();
node.SetParent(m_ParentNode);
}
node.internalTreeControl=m_TreeControl;
if(m_ParentNode!=null) m_ParentNode.OnChildNodeInserted(node);
TreeGX tree = GetTreeControl();
if(tree!=null)
tree.InvokeAfterNodeInsert(m_SourceAction, value as Node, m_ParentNode);
m_SourceAction = eTreeAction.Code;
}
/// <summary>
/// Copies collection into the specified array.
/// </summary>
/// <param name="array">Array to copy collection to.</param>
/// <param name="index">Starting index.</param>
public void CopyTo(Node[] array, int index)
{
List.CopyTo(array, index);
}
/// <summary>
/// Copies contained items to the Node array.
/// </summary>
/// <param name="array">Array to copy to.</param>
internal void CopyTo(Node[] array)
{
List.CopyTo(array,0);
}
protected override void OnClear()
{
foreach(Node node in this.List)
{
node.SetParent(null);
node.internalTreeControl=null;
}
base.OnClear();
}
protected override void OnClearComplete()
{
if (m_TreeControl != null && !PassiveCollection)
{
m_TreeControl.OnNodesCleared();
}
else if (m_ParentNode != null && !PassiveCollection)
m_ParentNode.OnNodesCleared();
TreeGX tree = GetTreeControl();
if (tree != null)
{
tree.ValidateSelectedNode();
}
base.OnClearComplete();
}
private TreeGX GetTreeControl()
{
if(m_TreeControl!=null)
return m_TreeControl;
if(m_ParentNode!=null)
return m_ParentNode.TreeControl;
return null;
}
private bool _PassiveCollection = false;
internal bool PassiveCollection
{
get { return _PassiveCollection; }
set
{
_PassiveCollection = value;
}
}
#endregion
}
#region NodeCollectionEditor
/// <summary>
/// Support for Node tabs design-time editor.
/// </summary>
public class NodeCollectionEditor:System.ComponentModel.Design.CollectionEditor
{
public NodeCollectionEditor(Type type):base(type)
{
}
protected override Type CreateCollectionItemType()
{
return typeof(Node);
}
protected override Type[] CreateNewItemTypes()
{
return new Type[] {typeof(Node)};
}
protected override object CreateInstance(Type itemType)
{
object item=base.CreateInstance(itemType);
if(item is Node)
{
Node node=item as Node;
node.Text=node.Name;
}
return item;
}
}
#endregion
}

View File

@@ -0,0 +1,203 @@
using System;
using System.Drawing;
using System.ComponentModel;
namespace DevComponents.Tree
{
/// <summary>
/// Represents node connector. Node connector is the line that is drawn to indicate connection between child and parent node.
/// </summary>
[ToolboxItem(false),System.ComponentModel.DesignTimeVisible(false),TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
public class NodeConnector:Component
{
#region Private Variables
private int m_LineWidth=1;
private Color m_LineColor=SystemColors.Highlight;
private eNodeConnectorType m_ConnectorType=eNodeConnectorType.Curve;
private bool m_UnderlineNoBorderNode=true;
private eConnectorCap m_EndCap=eConnectorCap.Ellipse;
//private eConnectorCap m_StartCap=eConnectorCap.None;
private Size m_EndCapSize=new Size(5,5);
//private Size m_StartCapSize=new Size(5,5);
#endregion
#region Events
/// <summary>
/// Occurs when appearance of the connector has changed as result of changed settings on the connector.
/// </summary>
public event EventHandler AppearanceChanged;
#endregion
#region Public Interface
/// <summary>
/// Default Constructor.
/// </summary>
public NodeConnector()
{
}
/// <summary>
/// Creates new instance of the object with specified parameters.
/// </summary>
/// <param name="lineWidth">Connector line width.</param>
/// <param name="type">Connector type.</param>
public NodeConnector(int lineWidth, eNodeConnectorType type)
{
this.LineWidth=lineWidth;
this.ConnectorType=type;
}
/// <summary>
/// Gets or sets the connector line width.
/// </summary>
[Browsable(true),DefaultValue(1),Category("Appearance"),Description("Indicates connector line width.")]
public int LineWidth
{
get {return m_LineWidth;}
set
{
m_LineWidth=value;
OnAppearanceChanged();
}
}
/// <summary>
/// Gets or sets the color of the connector line.
/// </summary>
[Browsable(true),Category("Appearance"),Description("Indicates color of the connector line.")]
public Color LineColor
{
get {return m_LineColor;}
set
{
m_LineColor=value;
OnAppearanceChanged();
}
}
/// <summary>
/// Returns true if editor should serialize LineColor property.
/// </summary>
[Browsable(false),EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeLineColor()
{
return m_LineColor!=SystemColors.Highlight;
}
/// <summary>
/// Gets or sets the type of the connector.
/// </summary>
/// <remarks>
/// See <see cref="eNodeConnectorType">eNodeConnectorType</see> enum for list of
/// available connectors.
/// </remarks>
/// <seealso cref="eNodeConnectorType">eNodeConnectorType Enumeration</seealso>
[Browsable(true),DefaultValue(eNodeConnectorType.Curve),Category("Appearance"),Description("Indicates visual type of the connector.")]
public eNodeConnectorType ConnectorType
{
get {return m_ConnectorType;}
set
{
m_ConnectorType=value;
OnAppearanceChanged();
}
}
/// <summary>
/// Gets or sets whether the child node without borders is underlined as a
/// continuation of the connector from node's parent. Default value is true.
/// </summary>
/// <remarks>
/// To enhance visual appearance of the connectors that are connecting to the node
/// with no borders assigned the connector is continued as a single line under the node
/// when this property is set to true (default) value.
/// </remarks>
[Browsable(true),DefaultValue(true),Category("Behavior"),Description("Indicates whether connector is drawn under the nodes with no borders assigned.")]
public bool UnderlineNoBorderNode
{
get {return m_UnderlineNoBorderNode;}
set
{
m_UnderlineNoBorderNode=value;
OnAppearanceChanged();
}
}
/// <summary>
/// Gets or sets the type of the cap that connector is ended with. Note that connector starts with parent node and ends with the child node. Default value is Ellipse.
/// </summary>
[Browsable(true),DefaultValue(eConnectorCap.Ellipse),Category("Appearance"),Description("Indicates type of the cap that connector is ended with.")]
public eConnectorCap EndCap
{
get {return m_EndCap;}
set
{
m_EndCap=value;
OnAppearanceChanged();
}
}
/// <summary>
/// Gets or sets the size of the end cap.
/// </summary>
[Browsable(true),Category("Appearance"),Description("Indicates the size of the end cap.")]
public System.Drawing.Size EndCapSize
{
get {return m_EndCapSize;}
set
{
m_EndCapSize=value;
OnAppearanceChanged();
}
}
/// <summary>
/// Returns true if EndCapSize property should be serialized by editor.
/// </summary>
/// <returns></returns>
[Browsable(false),EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeEndCapSize()
{
return (m_EndCapSize.Width!=5 || m_EndCapSize.Height!=5);
}
#endregion
#region Private Implementation
private void OnAppearanceChanged()
{
if(AppearanceChanged!=null)
AppearanceChanged(this,new EventArgs());
}
#endregion
// /// <summary>
// /// Gets or sets the type of the cap that connector is started with. Note that connector starts with parent node and ends with the child node. Default value is None.
// /// </summary>
// [Browsable(true),DefaultValue(eConnectorCap.None),Category("Appearance"),Description("Indicates type of the cap that connector is starts with.")]
// public eConnectorCap StartCap
// {
// get {return m_StartCap;}
// set {m_StartCap=value;}
// }
//
// /// <summary>
// /// Gets or sets the size of the start cap.
// /// </summary>
// [Browsable(true),Category("Appearance"),Description("Indicates the size of the start cap.")]
// public System.Drawing.Size StartCapSize
// {
// get {return m_StartCapSize;}
// set {m_StartCapSize=value;}
// }
//
// /// <summary>
// /// Returns true if StartCapSize property should be serialized by editor.
// /// </summary>
// /// <returns></returns>
// [Browsable(false),EditorBrowsable(EditorBrowsableState.Never)]
// public bool ShouldSerializeStartCapSize()
// {
// return (m_StartCapSize.Width!=5 || m_StartCapSize.Height!=5);
// }
}
}

View File

@@ -0,0 +1,86 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System.Windows.Forms;
using System.ComponentModel.Design;
namespace DevComponents.Tree
{
/// <summary>
/// Represents type editor for NodeConnector used for Windows Forms design-time support.
/// </summary>
public class NodeConnectorTypeEditor:System.Drawing.Design.UITypeEditor
{
#region Private Variables
private IWindowsFormsEditorService m_EditorService = null;
private const string OPTION_CREATE="Create new connector";
private const string OPTION_REMOVE="Remove connector";
#endregion
#region Internal Implementation
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (context != null
&& context.Instance != null
&& provider != null)
{
NodeConnector conn=value as NodeConnector;
m_EditorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
if(m_EditorService!=null)
{
ListBox lb=new ListBox();
lb.SelectedIndexChanged+=new EventHandler(this.SelectedChanged);
if(conn==null)
lb.Items.Add(OPTION_CREATE);
else
lb.Items.Add(OPTION_REMOVE);
m_EditorService.DropDownControl(lb);
IDesignerHost dh=(IDesignerHost)provider.GetService(typeof(IDesignerHost));
if(lb.SelectedItem!=null && dh!=null)
{
if(lb.SelectedItem.ToString()==OPTION_CREATE)
{
NodeConnector nd=dh.CreateComponent(typeof(NodeConnector)) as NodeConnector;
nd.LineWidth = 5;
value = nd;
}
else if(lb.SelectedItem.ToString()==OPTION_REMOVE)
{
value=null;
dh.DestroyComponent(conn);
}
}
}
}
return value;
}
private void SelectedChanged(object sender, EventArgs e)
{
if(m_EditorService!=null)
m_EditorService.CloseDropDown();
}
/// <summary>
/// Gets the editor style used by the EditValue method.
/// </summary>
/// <param name="context">An ITypeDescriptorContext that can be used to gain additional context information.</param>
/// <returns>A UITypeEditorEditStyle value that indicates the style of editor used by EditValue. If the UITypeEditor does not support this method, then GetEditStyle will return None</returns>
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
if (context != null && context.Instance != null)
{
return UITypeEditorEditStyle.DropDown;
}
return base.GetEditStyle(context);
}
#endregion
}
}

View File

@@ -0,0 +1,116 @@
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
namespace DevComponents.Tree
{
/// <summary>
/// Represents Windows Forms designer for Node object.
/// </summary>
public class NodeDesigner:ComponentDesigner
{
/// <summary>
/// Creates news instance of the class.
/// </summary>
public NodeDesigner()
{
}
public override void Initialize(IComponent component)
{
base.Initialize(component);
if(!component.Site.DesignMode)
return;
ISelectionService ss =(ISelectionService)GetService(typeof(ISelectionService));
if(ss!=null)
ss.SelectionChanged+=new EventHandler(OnSelectionChanged);
}
private void OnSelectionChanged(object sender, EventArgs e)
{
ISelectionService ss = (ISelectionService)sender;
if(ss.PrimarySelection!=this.Component)
{
Node node = this.Component as Node;
if(ss.PrimarySelection is Node)
{
Node selected=ss.PrimarySelection as Node;
if(selected.TreeControl!=node.TreeControl)
{
node.TreeControl.SelectedNode = null;
}
}
else
node.TreeControl.SelectedNode=null;
}
}
public override DesignerVerbCollection Verbs
{
get
{
DesignerVerb[] verbs = new DesignerVerb[]
{
new DesignerVerb("Create Child Node", new EventHandler(CreateNode))
};
return new DesignerVerbCollection(verbs);
}
}
private void CreateNode(object sender, EventArgs e)
{
CreateNode(this.Component as Node);
}
private Node CreateNode(Node parentNode)
{
IDesignerHost dh=(IDesignerHost)GetService(typeof(IDesignerHost));
if(dh==null)
return null;
Node node=null;
TreeGX tree=((Node)this.Component).TreeControl;
tree.BeginUpdate();
try
{
IComponentChangeService change=this.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
if(change!=null)
{
if(parentNode!=null)
change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(parentNode).Find("Nodes",true));
else
change.OnComponentChanging(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true));
}
node=dh.CreateComponent(typeof(Node)) as Node;
if(node!=null)
{
node.Text=node.Name;
node.Expanded = true;
if(parentNode==null)
tree.Nodes.Add(node);
else
{
parentNode.Nodes.Add(node);
parentNode.Expand();
}
if(change!=null)
{
if(parentNode!=null)
change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(parentNode).Find("Nodes",true),null,null);
else
change.OnComponentChanged(this.Component,TypeDescriptor.GetProperties(tree).Find("Nodes",true),null,null);
}
}
}
finally
{
tree.EndUpdate();
}
return node;
}
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Drawing;
using System.Collections;
namespace DevComponents.Tree
{
/// <summary>
/// Used to pass node contextual information used for layout of the node.
/// </summary>
internal class NodeLayoutContextInfo
{
public Node ContextNode=null;
public Rectangle ClientRectangle=Rectangle.Empty;
public int Left;
public int Top;
public ArrayList DefaultColumns=null;
public ArrayList ChildColumns=null;
public Font DefaultFont=null;
public ElementStyle DefaultCellStyle=null;
public ElementStyle DefaultNodeStyle=null;
public Size DefaultHeaderSize=Size.Empty;
public bool LeftToRight=true;
public bool HasExpandPart=true;
public System.Drawing.Graphics Graphics=null;
public ElementStyleCollection Styles=null;
public eCellLayout CellLayout=eCellLayout.Horizontal;
public eCellPartLayout CellPartLayout=eCellPartLayout.Horizontal;
public bool MapPositionNear=false;
}
}

View File

@@ -0,0 +1,831 @@
using System;
using System.Drawing;
using System.Text;
using DevComponents.Tree.Display;
namespace DevComponents.Tree
{
/// <summary>
/// Represents node operations.
/// </summary>
internal class NodeOperations
{
/// <summary>
/// Returns full path to the given node.
/// </summary>
/// <param name="node">Node to return path to.</param>
/// <returns>Full path to the node.</returns>
public static string GetFullPath(Node node,string pathSeparator)
{
if(node==null)
throw new ArgumentNullException("node");
StringBuilder sb=new StringBuilder(node.Text);
node=node.Parent;
while(node!=null)
{
sb.Insert(0,pathSeparator+node.Text);
node=node.Parent;
}
return sb.ToString();
}
/// <summary>
/// Gets the last child tree node. The LastNode is the last child Node in the NodeCollection stored in the Nodes property of the current tree node. If the Node has no child tree node, the LastNode property returns a null reference (Nothing in Visual Basic).
/// </summary>
/// <param name="node">Reference node.</param>
/// <returns>Last node if found or null if there is no last node.</returns>
public static Node GetLastNode(Node node)
{
if(node.Nodes.Count>0)
{
return node.Nodes[node.Nodes.Count-1];
}
return null;
}
/// <summary>
/// Gets the next sibling tree node. The NextNode is the next sibling Node in the NodeCollection stored in the Nodes property of the tree node's parent Node. If there is no next tree node, the NextNode property returns a null reference (Nothing in Visual Basic).
/// </summary>
/// <param name="node">Reference node.</param>
/// <returns>Node object or null if node cannot be found.</returns>
public static Node GetNextNode(Node node)
{
if (node == null)
return null;
NodeCollection parentNodes = null;
if (node.Parent != null)
parentNodes = node.Parent.Nodes;
else if (node.internalTreeControl != null)
parentNodes = node.internalTreeControl.Nodes;
if (parentNodes != null)
{
int index = parentNodes.IndexOf(node);
if (index < parentNodes.Count - 1)
return parentNodes[index + 1];
}
return null;
}
/// <summary>
/// Returns next visible sibling tree node.
/// </summary>
/// <param name="node">Reference node</param>
/// <returns>Node object or null if next visible node cannot be found</returns>
public static Node GetNextVisibleSibling(Node node)
{
if(node==null)
return null;
Node ret = GetNextNode(node);
while(ret!=null && !ret.Visible)
ret = GetNextNode(ret);
return ret;
}
/// <summary>
/// Gets the next visible tree node. The NextVisibleNode can be a child, sibling, or a tree node from another branch. If there is no next tree node, the NextVisibleNode property returns a null reference (Nothing in Visual Basic).
/// </summary>
/// <param name="node">Reference node.</param>
/// <returns>Node object or null if node cannot be found.</returns>
public static Node GetAnyNextNode(Node node)
{
Node nextNode = null;
// Walk into the child nodes
if (node.Nodes.Count > 0)
{
return node.Nodes[0];
}
// Get next sibling
nextNode = GetNextNode(node);
// Walk-up...
if (nextNode == null)
{
while (nextNode == null && node != null)
{
node = node.Parent;
nextNode = GetNextNode(node);
}
}
return nextNode;
}
/// <summary>
/// Gets the next visible tree node. The NextVisibleNode can be a child, sibling, or a tree node from another branch. If there is no next tree node, the NextVisibleNode property returns a null reference (Nothing in Visual Basic).
/// </summary>
/// <param name="node">Reference node.</param>
/// <returns>Node object or null if node cannot be found.</returns>
public static Node GetNextVisibleNode(Node node)
{
Node nextVisibleNode = null;
// First see whether all parent nodes are expanded and if not find the first one that is
Node parent = node.Parent;
Node lastNotExpanded = null;
while (parent != null)
{
if (!parent.Expanded)
lastNotExpanded = parent;
parent = parent.Parent;
}
if (lastNotExpanded != null)
{
// Last parent node expanded
if (lastNotExpanded.Parent != null)
lastNotExpanded = lastNotExpanded.Parent;
while (lastNotExpanded != null)
{
lastNotExpanded = GetNextNode(lastNotExpanded);
if (lastNotExpanded != null && lastNotExpanded.Visible) return lastNotExpanded;
}
}
// Walk into the child nodes
if (node.Expanded && node.Nodes.Count > 0)
{
foreach (Node n in node.Nodes)
{
if (n.Visible) return n;
}
//return null;
}
// Get next sibling
nextVisibleNode = GetAnyNextNode(node);
while (nextVisibleNode != null)
{
if (nextVisibleNode.Visible && nextVisibleNode.IsVisible)
return nextVisibleNode;
nextVisibleNode = GetAnyNextNode(nextVisibleNode);
}
// Walk-up...
//while (nextVisibleNode == null && node != null)
//{
// node = node.Parent;
// nextVisibleNode = GetAnyNextNode(node);
// if (nextVisibleNode != null && !nextVisibleNode.Visible)
// nextVisibleNode = null;
//}
return nextVisibleNode;
}
/// <summary>
/// Gets a value indicating whether the tree node is visible. Node is considered to be visible when it's Visible property is set to true and path to the node is available i.e. all parent nodes are expanded.
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public static bool GetIsNodeVisible(Node node)
{
if(!node.Visible)
return false;
Node n=node;
while(n.Parent!=null)
{
n=n.Parent;
if(!n.Expanded || !n.Visible)
return false;
}
return true;
}
/// <summary>
/// Returns whether node is displayed on the screen and visible to the user. When node is outside of the viewable area this property will return false. It will also return false if node is not visible.
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public static bool GetIsNodeDisplayed(Node node)
{
if(!node.Visible || !GetIsNodeVisible(node))
return false;
TreeGX tree=node.TreeControl;
if(tree!=null)
{
if (tree.Zoom == 1)
{
Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, node, tree.NodeDisplay.Offset);
return tree.ClientRectangle.IntersectsWith(r);
}
else
{
Rectangle r = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds, node, tree.NodeDisplay.Offset);
Rectangle clientRect = tree.GetLayoutRectangle(tree.ClientRectangle);
return clientRect.IntersectsWith(r);
}
}
return false;
}
/// <summary>
/// Returns last rendered node on screen.
/// </summary>
/// <param name="tree">Tree control.</param>
/// <returns>Last rendered node or null</returns>
public static Node GetLastDisplayedNode(TreeGX tree)
{
Rectangle r = tree.ClientRectangle;
Node node = tree.SelectedNode;
if (node == null) node = GetFirstVisibleNode(tree);
Point scrollPos = Point.Empty;
if (tree.AutoScroll)
scrollPos = tree.GetAutoScrollPositionOffset();
// Find last fully rendered node
Node lastNode = null;
if (r.Contains(node.Bounds))
lastNode = node;
while (node != null)
{
node = NodeOperations.GetNextVisibleNode(node);
if (node != null && node.Selectable)
{
Rectangle nodeRect = NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeContentBounds, node, scrollPos);
if (r.Contains(nodeRect))
lastNode = node;
else if (nodeRect.Y > r.Bottom)
break;
}
}
return lastNode;
}
/// <summary>
/// Gets the zero based index of position of the tree node in the tree node collection. -1 is returned if node is not added to the nodes collection.
/// </summary>
/// <param name="node">Reference node.</param>
/// <returns>Zero based index or -1 if node is not in collection.</returns>
public static int GetNodeIndex(Node node)
{
if(node.Parent==null)
return -1;
return node.Parent.Nodes.IndexOf(node);
}
/// <summary>
/// Gets the previous sibling tree node. The PrevNode is the previous sibling Node in the NodeCollection stored in the Nodes property of the tree node's parent Node. If there is no previous tree node, the PrevNode property returns a null reference (Nothing in Visual Basic).
/// </summary>
/// <param name="node">Reference node.</param>
/// <returns>Node object or null if node cannot be found.</returns>
public static Node GetPreviousNode(Node node)
{
if (node == null)
return null;
NodeCollection parentNodes = null;
if (node.Parent != null)
parentNodes = node.Parent.Nodes;
else if (node.internalTreeControl != null)
parentNodes = node.internalTreeControl.Nodes;
if (parentNodes != null)
{
int index = parentNodes.IndexOf(node);
if (index > 0)
return parentNodes[index - 1];
}
return null;
}
/// <summary>
/// Gets the previous tree node. The Previous Node can be a child, sibling, or a tree node from another branch. If there is no previous tree node, the PrevNode property returns a null reference (Nothing in Visual Basic).
/// </summary>
/// <param name="node">Reference node.</param>
/// <returns>Node object or null if node cannot be found.</returns>
public static Node GetAnyPreviousNode(Node node)
{
Node prevNode = null;
Node referenceNode = node;
// Walk into the previous node parent
if (referenceNode.Parent != null)
{
if (referenceNode.Parent.Nodes.IndexOf(referenceNode) > 0)
{
prevNode = GetPreviousNode(referenceNode);
}
else
{
return referenceNode.Parent;
}
}
else if (referenceNode.TreeControl != null)
prevNode = GetPreviousNode(referenceNode);
else
return null;
if (prevNode == null)
return null;
// Walk into the node
while (prevNode.Nodes.Count > 0)
{
prevNode = prevNode.Nodes[prevNode.Nodes.Count - 1];
}
return prevNode;
}
/// <summary>
/// Gets the previous visible tree node. The PrevVisibleNode can be a child, sibling, or a tree node from another branch. If there is no previous tree node, the PrevVisibleNode property returns a null reference (Nothing in Visual Basic).
/// </summary>
/// <param name="node">Reference node.</param>
/// <returns>Node object or null if node cannot be found.</returns>
public static Node GetPreviousVisibleNode(Node node)
{
Node prevVisibleNode = null;
// First see whether all parent nodes are expanded and if not find the first one that is
Node referenceNode = node.Parent;
Node lastNotExpanded = null;
while (referenceNode != null)
{
if (!referenceNode.Expanded)
lastNotExpanded = referenceNode;
referenceNode = referenceNode.Parent;
}
if (lastNotExpanded != null)
{
if (lastNotExpanded.IsVisible) return lastNotExpanded;
referenceNode = lastNotExpanded;
}
else
referenceNode = node;
// Walk into the previous node parent
if (referenceNode.Parent != null)
{
if (referenceNode.Parent.Nodes.IndexOf(referenceNode) > 0)
{
prevVisibleNode = GetAnyPreviousNode(referenceNode);
while (prevVisibleNode != null)
{
if (prevVisibleNode.IsVisible) break;
prevVisibleNode = GetAnyPreviousNode(prevVisibleNode);
}
if (prevVisibleNode != null) return prevVisibleNode;
}
else
{
while (referenceNode.Parent != null)
{
if (referenceNode.Parent.IsVisible)
return referenceNode.Parent;
referenceNode = referenceNode.Parent;
}
if (referenceNode.TreeControl != null)
prevVisibleNode = GetAnyPreviousNode(referenceNode);
}
}
else if (referenceNode.TreeControl != null)
{
prevVisibleNode = GetPreviousNode(referenceNode);
if (prevVisibleNode != null && (!prevVisibleNode.Visible || !prevVisibleNode.Selectable))
{
while (prevVisibleNode != null && !(prevVisibleNode.Visible || prevVisibleNode.Selectable))
prevVisibleNode = GetPreviousNode(prevVisibleNode);
}
}
else
return null;
if (prevVisibleNode == null)
return null;
// Walk into the node
while (prevVisibleNode.Expanded && prevVisibleNode.Nodes.Count > 0)
{
prevVisibleNode = prevVisibleNode.Nodes[prevVisibleNode.Nodes.Count - 1];
}
return prevVisibleNode;
}
/// <summary>
/// Returns true if node passed is considered root node for display purposes.
/// </summary>
/// <param name="tree">Reference to the tree control.</param>
/// <param name="node">Node to test.</param>
/// <returns>true if node is root node for display purposes otherwise false.</returns>
public static bool IsRootNode(TreeGX tree, Node node)
{
if(node.Parent==null || node==tree.DisplayRootNode)
return true;
return false;
}
/// <summary>
/// Ensures that the node is visible, expanding nodes and scrolling the control as necessary.
/// </summary>
/// <param name="reference">Node to be made visible.</param>
public static void EnsureVisible(Node reference)
{
// First expand all parents
TreeGX tree=reference.TreeControl;
if(tree!=null)
tree.SuspendPaint=true;
try
{
Node node=reference;
bool layout=false;
while(node.Parent!=null)
{
if(!node.Parent.Expanded)
{
node.Parent.Expand();
layout=true;
}
node=node.Parent;
}
if(layout)
tree.RecalcLayoutInternal();
Rectangle r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds,reference,tree.NodeDisplay.Offset);
if(tree!=null && tree.AutoScroll)
{
if(tree.Zoom!=1)
{
r = tree.GetScreenRectangle(r);
}
r.Offset(-tree.AutoScrollPosition.X,-tree.AutoScrollPosition.Y);
Rectangle treeClientRectangle = tree.GetInnerRectangle();
if(!treeClientRectangle.Contains(r))
{
Point p=Point.Empty;
if(r.Right>treeClientRectangle.Right)
p.X=r.Right-treeClientRectangle.Right;
else if(r.X<treeClientRectangle.X)
p.X=r.X;
if(r.Bottom>treeClientRectangle.Bottom)
p.Y = r.Y - r.Height;
else if(r.Y<treeClientRectangle.Y)
p.Y=r.Y;
// Scroll it to show the node
tree.AutoScrollPosition=p;
}
}
}
finally
{
if(tree!=null)
tree.SuspendPaint=false;
}
}
/// <summary>
/// Returns number of visible child nodes for given node.
/// </summary>
/// <param name="node">Reference node.</param>
/// <returns>Number of visible child nodes.</returns>
public static int GetVisibleNodesCount(Node node)
{
if(node.Nodes.Count==0)
return 0;
int count=0;
foreach(Node n in node.Nodes)
{
if(n.Visible)
count++;
}
return count;
}
/// <summary>
/// Gets first visible node.
/// </summary>
/// <param name="tree">Reference to tree.</param>
/// <returns>Last visible node found or null</returns>
public static Node GetFirstVisibleNode(TreeGX tree)
{
if (tree.Nodes.Count == 0) return null;
Node node = tree.DisplayRootNode == null ? tree.Nodes[0] : tree.DisplayRootNode;
if (node.Visible)
return node;
return GetNextVisibleNode(node);
}
/// <summary>
/// Returns true if node has at least single visible child node.
/// </summary>
/// <param name="node">Reference node.</param>
/// <returns>True if at least single child node is visible otherwise false.</returns>
public static bool GetAnyVisibleNodes(Node node)
{
if(node.Nodes.Count==0)
return false;
foreach(Node n in node.Nodes)
{
if(n.Visible)
return true;
}
return false;
}
/// <summary>
/// Retrieves the tree node that is at the specified location.
/// </summary>
/// <returns>The Node at the specified point, in tree view coordinates.</returns>
/// <remarks>
/// <para>You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the
/// MouseDown event as the x and y parameters.</para>
/// </remarks>
/// <param name="p">The Point to evaluate and retrieve the node from.</param>
/// <param name="tree">Tree control to find node at.</param>
public static Node GetNodeAt(TreeGX tree, Point p)
{
return GetNodeAt(tree,p.X,p.Y);
}
/// <summary>
/// Retrieves the tree node that is at the specified location.
/// </summary>
/// <returns>The TreeNode at the specified location, in tree view coordinates.</returns>
/// <remarks>
/// <para>You can pass the MouseEventArgs.X and MouseEventArgs.Y coordinates of the
/// MouseDown event as the x and y parameters.</para>
/// </remarks>
/// <param name="x">The X position to evaluate and retrieve the node from.</param>
/// <param name="y">The Y position to evaluate and retrieve the node from.</param>
/// <param name="tree">Tree control to find node at.</param>
public static Node GetNodeAt(TreeGX tree, int x, int y)
{
if (tree.Nodes.Count == 0 || !tree.DisplayRectangle.Contains(x, y) && tree.Zoom == 1)
return null;
Node node=tree.Nodes[0];
Node retNode=null;
if(tree.DisplayRootNode!=null)
node=tree.DisplayRootNode;
while(node!=null)
{
Rectangle r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds,node,tree.NodeDisplay.Offset);
if(r.Contains(x,y))
{
retNode=node;
break;
}
r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ChildNodeBounds,node,tree.NodeDisplay.Offset);
if(!r.Contains(x,y))
node = GetNextVisibleSibling(node);
else
node=node.NextVisibleNode;
}
return retNode;
}
public static TreeAreaInfo GetTreeAreaInfo(TreeGX tree, int x, int y)
{
TreeAreaInfo areaInfo=new TreeAreaInfo();
if (tree.Nodes.Count == 0 || !tree.DisplayRectangle.Contains(x, y) && tree.Zoom == 1)
return null;
Node node=tree.Nodes[0];
if(tree.DisplayRootNode!=null)
node = tree.DisplayRootNode;
Node dragNode = tree.GetDragNode();
Rectangle dragNodeBounds=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds,dragNode,tree.NodeDisplay.Offset);
if(dragNodeBounds.Contains(x,y))
{
areaInfo.NodeAt=dragNode;
return areaInfo;
}
int dragNodeWidth = dragNode.BoundsRelative.Width;
Node previousNode = null;
Rectangle previousRect=Rectangle.Empty;
if(tree.DisplayRootNode!=null)
node=tree.DisplayRootNode;
while(node!=null)
{
if(!node.IsDisplayed)
{
node = node.NextVisibleNode;
continue;
}
Rectangle r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.NodeBounds,node,tree.NodeDisplay.Offset);
if(r.Contains(x,y))
{
areaInfo.NodeAt = node;
break;
}
if(previousNode!=null && node.Parent==previousNode.Parent)
{
Rectangle totalArea;
if(r.Width<dragNodeWidth || previousRect.Width<dragNodeWidth)
{
totalArea =
Rectangle.Union(new Rectangle(r.Location, new Size(dragNodeWidth, r.Height)),
new Rectangle(previousRect.Location, new Size(dragNodeWidth, previousRect.Height)));
}
else
totalArea=Rectangle.Union(r,previousRect);
if(totalArea.Contains(x,y))
{
Rectangle r1 = r;
Rectangle r2 = previousRect;
if(totalArea.Width>r1.Width) r1.Width = totalArea.Width;
if(totalArea.Width>r2.Width) r2.Width = totalArea.Width;
if(!r1.Contains(x,y) && !r2.Contains(x,y))
{
areaInfo.PreviousNode = previousNode;
areaInfo.NextNode = node;
areaInfo.NodeAt = null;
areaInfo.ParentAreaNode = node.Parent;
break;
}
}
}
previousNode = node;
previousRect = r;
//r=NodeDisplay.GetNodeRectangle(eNodeRectanglePart.ChildNodeBounds,node,tree.NodeDisplay.Offset);
//if (!r.Contains(x, y))
// node = GetNextVisibleSibling(node);
//else
node = node.NextVisibleNode;
}
return areaInfo;
}
/// <summary>
/// Gets the count of visible child nodes (Visible=true) for given node.
/// </summary>
/// <param name="parent">Reference to Node object.</param>
/// <returns>Number of visible nodes.</returns>
public static int GetVisibleChildNodesCount(Node parent)
{
int count = 0;
foreach(Node node in parent.Nodes)
{
if(node.Visible)
count++;
}
return count;
}
/// <summary>
/// Gets the first visible child node or returns null if node cannot be found.
/// </summary>
/// <param name="parent">Reference to Node object.</param>
/// <returns>First visible node or null if node cannot be found.</returns>
public static Node GetFirstVisibleChildNode(Node parent)
{
foreach(Node node in parent.Nodes)
{
if(node.Visible)
return node;
}
return null;
}
#region Licensing
#if !TRIAL
internal static bool keyValidated=false;
internal static int keyValidated2=0;
internal static bool ValidateLicenseKey(string key)
{
bool ret = false;
string[] parts = key.Split('-');
int i = 10;
foreach(string s in parts)
{
if(s=="88405280")
i++;
else if(s=="D06E")
i += 10;
else if(s=="4617")
i += 8;
else if(s=="8810")
i += 12;
else if(s=="64462F60FA93")
i += 3;
}
if(i==29)
return true;
keyValidated = true;
return ret;
}
internal static bool CheckLicenseKey(string key)
{
// {EB364C34-3CE3-4cd6-BB1B-13513ABE0D62}, 114
string[] parts = key.Split('-');
int test = 0;
for(int i=parts.Length-1;i>=0;i--)
{
if(parts[i]=="3CE3")
test += 12;
else if(parts[i]=="13513ABE0D62")
test += 2;
else if(parts[i]=="4cd6")
test += 3;
else if(parts[i]=="BB1B")
test += 7;
else if(parts[i]=="EB364C34")
test += 13;
}
keyValidated2 = test + 77;
if(test==23)
return false;
return true;
}
#endif
#if TRIAL
private static Color m_ColorExpFlag=Color.Empty;
internal static int ColorCountExp=0;
internal static bool ColorExpAlt()
{
Color clr=SystemColors.Control;
Color clr2;
Color clr3;
clr2=clr;
if(clr2.ToArgb()==clr.ToArgb())
{
clr3=clr2;
}
else
{
clr3=clr;
}
ColorCountExp=clr.A;
if(!m_ColorExpFlag.IsEmpty)
{
return (m_ColorExpFlag==Color.Black?false:true);
}
try
{
Microsoft.Win32.RegistryKey key=Microsoft.Win32.Registry.ClassesRoot;
key=key.CreateSubKey("CLSID\\{EB84498D-DBDA-4806-A10C-B668BD4F1BB1}\\InprocServer32");
try
{
if(key.GetValue("")==null || key.GetValue("").ToString()=="")
{
key.SetValue("",DateTime.Today.ToOADate().ToString());
}
else
{
if(key.GetValue("").ToString()=="windows3.dll")
{
m_ColorExpFlag=Color.White;
key.Close();
key=null;
return true;
}
DateTime date=DateTime.FromOADate(double.Parse(key.GetValue("").ToString()));
if(((TimeSpan)DateTime.Today.Subtract(date)).TotalDays>30)
{
m_ColorExpFlag=Color.White;
key.SetValue("","windows3.dll");
key.Close();
key=null;
return true;
}
if(((TimeSpan)DateTime.Today.Subtract(date)).TotalDays<0)
{
m_ColorExpFlag=Color.White;
key.SetValue("","windows2.dll");
key.Close();
key=null;
return true;
}
}
}
finally
{
if(key!=null)
key.Close();
}
}
catch{}
m_ColorExpFlag=Color.Black;
return false;
}
#endif
#endregion
}
}

View File

@@ -0,0 +1,462 @@
using System;
using System.ComponentModel;
using System.Drawing;
namespace DevComponents.Tree
{
/// <summary>
/// Class that provides predefined styles for the nodes. Styles are defined as static memeber of the class
/// </summary>
public class NodeStyles
{
private static ElementStyle s_AppleStyle=null;
private static ElementStyle s_BlueStyle=null;
private static ElementStyle s_BlueLightStyle=null;
private static ElementStyle s_BlueNightStyle=null;
private static ElementStyle s_BlueMistStyle=null;
private static ElementStyle s_CyanStyle=null;
private static ElementStyle s_GreenStyle=null;
private static ElementStyle s_LemonStyle=null;
private static ElementStyle s_MagentaStyle=null;
private static ElementStyle s_OrangeStyle=null;
private static ElementStyle s_OrangeLightStyle=null;
private static ElementStyle s_PurpleStyle=null;
private static ElementStyle s_PurpleMistStyle=null;
private static ElementStyle s_RedStyle=null;
private static ElementStyle s_SilverStyle=null;
private static ElementStyle s_SilverMistStyle=null;
private static ElementStyle s_TanStyle=null;
private static ElementStyle s_TealStyle=null;
private static ElementStyle s_YellowStyle=null;
private static ElementStyle s_GrayStyle=null;
/// <summary>
/// Returns Apple element style
/// </summary>
public static ElementStyle Apple
{
get
{
if(s_AppleStyle==null)
s_AppleStyle = GetStyle(ePredefinedElementStyle.Apple);
return s_AppleStyle;
}
}
/// <summary>
/// Returns Blue element style
/// </summary>
public static ElementStyle Blue
{
get
{
if(s_BlueStyle==null)
s_BlueStyle= GetStyle(ePredefinedElementStyle.Blue);
return s_BlueStyle;
}
}
/// <summary>
/// Returns BlueLight element style
/// </summary>
public static ElementStyle BlueLight
{
get
{
if(s_BlueLightStyle==null)
s_BlueLightStyle= GetStyle(ePredefinedElementStyle.BlueLight);
return s_BlueLightStyle;
}
}
/// <summary>
/// Returns BlueNight element style
/// </summary>
public static ElementStyle BlueNight
{
get
{
if(s_BlueNightStyle==null)
s_BlueNightStyle= GetStyle(ePredefinedElementStyle.BlueNight);
return s_BlueNightStyle;
}
}
/// <summary>
/// Returns BlueMist element style
/// </summary>
public static ElementStyle BlueMist
{
get
{
if(s_BlueMistStyle==null)
s_BlueMistStyle= GetStyle(ePredefinedElementStyle.BlueMist);
return s_BlueMistStyle;
}
}
/// <summary>
/// Returns Cyan element style
/// </summary>
public static ElementStyle Cyan
{
get
{
if(s_CyanStyle==null)
s_CyanStyle= GetStyle(ePredefinedElementStyle.Cyan);
return s_CyanStyle;
}
}
/// <summary>
/// Returns Green element style
/// </summary>
public static ElementStyle Green
{
get
{
if(s_GreenStyle==null)
s_GreenStyle= GetStyle(ePredefinedElementStyle.Green);
return s_GreenStyle;
}
}
/// <summary>
/// Returns Lemon element style
/// </summary>
public static ElementStyle Lemon
{
get
{
if(s_LemonStyle==null)
s_LemonStyle= GetStyle(ePredefinedElementStyle.Lemon);
return s_LemonStyle;
}
}
/// <summary>
/// Returns Magenta element style
/// </summary>
public static ElementStyle Magenta
{
get
{
if(s_MagentaStyle==null)
s_MagentaStyle= GetStyle(ePredefinedElementStyle.Magenta);
return s_MagentaStyle;
}
}
/// <summary>
/// Returns Orange element style
/// </summary>
public static ElementStyle Orange
{
get
{
if(s_OrangeStyle==null)
s_OrangeStyle= GetStyle(ePredefinedElementStyle.Orange);
return s_OrangeStyle;
}
}
/// <summary>
/// Returns OrangeLight element style
/// </summary>
public static ElementStyle OrangeLight
{
get
{
if(s_OrangeLightStyle==null)
s_OrangeLightStyle= GetStyle(ePredefinedElementStyle.OrangeLight);
return s_OrangeLightStyle;
}
}
/// <summary>
/// Returns Purple element style
/// </summary>
public static ElementStyle Purple
{
get
{
if(s_PurpleStyle==null)
s_PurpleStyle= GetStyle(ePredefinedElementStyle.Purple);
return s_PurpleStyle;
}
}
/// <summary>
/// Returns PurpleMist element style
/// </summary>
public static ElementStyle PurpleMist
{
get
{
if(s_PurpleMistStyle==null)
s_PurpleMistStyle= GetStyle(ePredefinedElementStyle.PurpleMist);
return s_PurpleMistStyle;
}
}
/// <summary>
/// Returns Red element style
/// </summary>
public static ElementStyle Red
{
get
{
if(s_RedStyle==null)
s_RedStyle= GetStyle(ePredefinedElementStyle.Red);
return s_RedStyle;
}
}
/// <summary>
/// Returns Silver element style
/// </summary>
public static ElementStyle Silver
{
get
{
if(s_SilverStyle==null)
s_SilverStyle= GetStyle(ePredefinedElementStyle.Silver);
return s_SilverStyle;
}
}
/// <summary>
/// Returns SilverMist element style
/// </summary>
public static ElementStyle SilverMist
{
get
{
if(s_SilverMistStyle==null)
s_SilverMistStyle= GetStyle(ePredefinedElementStyle.SilverMist);
return s_SilverMistStyle;
}
}
/// <summary>
/// Returns Tan element style
/// </summary>
public static ElementStyle Tan
{
get
{
if(s_TanStyle==null)
s_TanStyle= GetStyle(ePredefinedElementStyle.Tan);
return s_TanStyle;
}
}
/// <summary>
/// Returns Teal element style
/// </summary>
public static ElementStyle Teal
{
get
{
if(s_TealStyle==null)
s_TealStyle= GetStyle(ePredefinedElementStyle.Teal);
return s_TealStyle;
}
}
/// <summary>
/// Returns Yellow element style
/// </summary>
public static ElementStyle Yellow
{
get
{
if(s_YellowStyle==null)
s_YellowStyle= GetStyle(ePredefinedElementStyle.Yellow);
return s_YellowStyle;
}
}
/// <summary>
/// Returns Gray element style
/// </summary>
public static ElementStyle Gray
{
get
{
if(s_GrayStyle==null)
s_GrayStyle= GetStyle(ePredefinedElementStyle.Gray);
return s_GrayStyle;
}
}
private static ElementStyle GetStyle(ePredefinedElementStyle c)
{
Color color1=Color.Empty;
Color color2=Color.Empty;
int gradientAngle = 90;
Color textColor=Color.Black;
Color borderColor = Color.DarkGray;
switch (c)
{
case ePredefinedElementStyle.Apple:
{
color1 = Color.FromArgb(232, 248, 224);
color2 = Color.FromArgb(173, 231, 146);
break;
}
case ePredefinedElementStyle.Blue:
{
color1 = Color.FromArgb(221, 230, 247);
color2 = Color.FromArgb(138, 168, 228);
break;
}
case ePredefinedElementStyle.BlueLight:
{
color1=Color.FromArgb(255,255,255);
color2=Color.FromArgb(210,224,252);
textColor=Color.FromArgb(69,84,115);
break;
}
case ePredefinedElementStyle.BlueMist:
{
color1 = Color.FromArgb(227, 236, 243);
color2 = Color.FromArgb(155, 187, 210);
break;
}
case ePredefinedElementStyle.BlueNight:
{
color1=Color.FromArgb(77,108,152);
color2=Color.Navy;
textColor=Color.White;
borderColor=Color.Navy;
break;
}
case ePredefinedElementStyle.Cyan:
{
color1 = Color.FromArgb(227, 236, 243);
color2 = Color.FromArgb(155, 187, 210);
break;
}
case ePredefinedElementStyle.Green:
{
color1 = Color.FromArgb(234, 240, 226);
color2 = Color.FromArgb(183, 201, 151);
break;
}
case ePredefinedElementStyle.Lemon:
{
color1 = Color.FromArgb(252, 253, 215);
color2 = Color.FromArgb(245, 249, 111);
break;
}
case ePredefinedElementStyle.Magenta:
{
color1 = Color.FromArgb(243, 229, 236);
color2 = Color.FromArgb(213, 164, 187);
break;
}
case ePredefinedElementStyle.Orange:
{
color1 = Color.FromArgb(252, 233, 217);
color2 = Color.FromArgb(246, 176, 120);
break;
}
case ePredefinedElementStyle.OrangeLight:
{
color1=Color.FromArgb(255,239,201);
color2=Color.FromArgb(242,210,132);
textColor=Color.FromArgb(117,83,2);
break;
}
case ePredefinedElementStyle.Purple:
{
color1 = Color.FromArgb(234, 227, 245);
color2 = Color.FromArgb(180, 158, 222);
break;
}
case ePredefinedElementStyle.PurpleMist:
{
color1 = Color.FromArgb(232, 227, 234);
color2 = Color.FromArgb(171, 156, 183);
break;
}
case ePredefinedElementStyle.Red:
{
color1 = Color.FromArgb(249, 225, 226);
color2 = Color.FromArgb(238, 149, 151);
break;
}
case ePredefinedElementStyle.Silver:
{
color1 = Color.FromArgb(225, 225, 232);
color2 = Color.FromArgb(149, 149, 170);
break;
}
case ePredefinedElementStyle.SilverMist:
{
color1 = Color.FromArgb(243,244,250);
color2=Color.FromArgb(155,153,183);
textColor=Color.FromArgb(87,86,113);
break;
}
case ePredefinedElementStyle.Tan:
{
color1 = Color.FromArgb(248, 242, 226);
color2 = Color.FromArgb(232, 209, 153);
break;
}
case ePredefinedElementStyle.Teal:
{
color1 = Color.FromArgb(205, 236, 240);
color2 = Color.FromArgb(78, 188, 202);
break;
}
case ePredefinedElementStyle.Yellow:
{
color1 = Color.FromArgb(255, 244, 213);
color2 = Color.FromArgb(255, 216, 105);
break;
}
case ePredefinedElementStyle.Gray:
{
color1 = Color.White;
color2 = ColorScheme.GetColor("E4E4F0");
break;
}
}
ElementStyle style=Utilites.CreateStyle(new ComponentFactory(),Enum.GetName(typeof(ePredefinedElementStyle),c),borderColor,color1, color2, gradientAngle,textColor);
return style;
}
}
/// <summary>
/// Indicates predefined element style.
/// </summary>
public enum ePredefinedElementStyle
{
Blue,
BlueLight,
BlueNight,
Yellow,
Green,
Red,
Purple,
Cyan,
Orange,
OrangeLight,
Magenta,
BlueMist,
PurpleMist,
Tan,
Lemon,
Apple,
Teal,
Silver,
SilverMist,
Gray
}
}

View File

@@ -0,0 +1,235 @@
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
namespace DevComponents.Tree
{
/// <summary>
/// Summary description for NodeTreeLayout.
/// </summary>
internal class NodeTreeLayout:NodeLayout
{
//private bool m_LayoutPerformed=false;
public NodeTreeLayout(TreeGX treeControl, Rectangle clientArea):base(treeControl,clientArea)
{
//m_ExpandAreaWidth=16;
m_ExpandPartSize=new Size(9,9);
}
public override void PerformLayout()
{
this.PrepareStyles();
// Get default Columns
ArrayList defaultColInfoList=this.GetDefaultColumnInfo();
Graphics graphics=this.GetGraphics();
try
{
// Loop through each top-level node
Node[] topLevelNodes=this.GetTopLevelNodes();
NodeLayoutContextInfo layoutInfo=GetDefaultNodeLayoutContextInfo(GetGraphics());
foreach(Node childNode in topLevelNodes)
{
layoutInfo.ContextNode=childNode;
ProcessNode(layoutInfo);
}
}
finally
{
graphics.Dispose();
}
}
#region Node routines
private void ProcessNode(NodeLayoutContextInfo layoutInfo)
{
Node node=layoutInfo.ContextNode;
if(node.SizeChanged)
{
// Calculate size of the node itself...
LayoutNode(layoutInfo);
// Calculate size and location of node column header if any
// if(node.NodesColumnHeaderVisible)
// {
// layoutInfo.Left+=this.NodeLevelOffset;
// LayoutColumnHeader(layoutInfo);
// layoutInfo.Left-=this.NodeLevelOffset;
// }
}
else if(node.Bounds.Top!=layoutInfo.Top)
{
// Adjust top position
node.SetBounds(new Rectangle(node.Bounds.X,layoutInfo.Top,node.Bounds.Width,node.Bounds.Height));
foreach(Cell c in node.Cells)
c.SetBounds(new Rectangle(c.Bounds.X,layoutInfo.Top,c.Bounds.Width,c.Bounds.Height));
}
// Need to set the Top position properly
layoutInfo.Top+=(node.Bounds.Height+this.NodeVerticalSpacing);
// if(node.Expanded && node.NodesColumnHeaderVisible && node.NodesColumns.Count>0)
// layoutInfo.Top+=node.ColumnHeaderHeight;
if(node.Expanded)
{
int originalLevelOffset=layoutInfo.Left;
layoutInfo.Left+=this.NodeLevelOffset;
ArrayList parentColumns=layoutInfo.ChildColumns;
ArrayList childColumns=GetNodeColumnInfo(node);
foreach(Node childNode in node.Nodes)
{
layoutInfo.ContextNode=childNode;
layoutInfo.ChildColumns=childColumns;
ProcessNode(layoutInfo);
}
layoutInfo.ChildColumns=parentColumns;
layoutInfo.ContextNode=node;
layoutInfo.Left=originalLevelOffset;
}
}
// private void LayoutNode(NodeLayoutContextInfo layoutInfo)
// {
// if(!layoutInfo.ContextNode.SizeChanged)
// return;
//
// Node node=layoutInfo.ContextNode;
// Rectangle nodeContentRect=Rectangle.Empty; // Node content rect excludes expand rect
//
// Rectangle nodeRect=Rectangle.Empty;
// nodeRect.X=layoutInfo.Left;
// nodeRect.Y=layoutInfo.Top;
//
// int height=0, width=0;
//
// bool bExpandPartAlignedNear=this.ExpandPartAlignedNear(node);
// if(bExpandPartAlignedNear)
// {
// width+=(this.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); // nodeStyle.MarginLeft+nodeStyle.PaddingLeft;
// y+=ElementStyleLayout.TopWhiteSpace(nodeStyle); // nodeStyle.MarginTop+nodeStyle.PaddingTop;
// nodeContentRect.X+=nodeStyle.MarginLeft;
// nodeContentRect.Y+=nodeStyle.MarginTop;
// }
//
// Size size=this.GetCellLayout().LayoutCells(layoutInfo,x,y);
// height=size.Height;
// width+=size.Width;
//
// nodeContentRect.Width=size.Width;
// nodeContentRect.Height=size.Height;
//
// node.SetCellsBounds(new Rectangle(x,y,size.Width,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(!bExpandPartAlignedNear)
// width+=this.ExpandAreaWidth;
//
// nodeRect.Height=height;
// nodeRect.Width=width;
//
// node.SetBounds(nodeRect);
// node.SetContentBounds(nodeContentRect);
//
// LayoutExpandPart(layoutInfo,true);
//
// node.SizeChanged=false;
// }
/// <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 override bool ReserveExpandPartSpace
{
get
{
return true;
}
}
//
// private CellLayout m_CellLayout=null;
// private CellLayout GetCellLayout()
// {
// if(m_CellLayout==null)
// m_CellLayout=new CellLayout();
// return m_CellLayout;
// }
// /// <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>
// private void LayoutExpandPart(NodeLayoutContextInfo layoutInfo)
// {
// Node node=layoutInfo.ContextNode;
//
// Size partSize=new Size(9,9);
//
// // For different styles of the nodes the expand part +/- might be aligned to the right of the node etc.
// // this routine does default left position
// Rectangle bounds=new Rectangle(0,0,partSize.Width,partSize.Height);
// bounds.Y=(node.Bounds.Height-bounds.Height)/2;
// bounds.X=(this.ExpandAreaWidth-bounds.Width)/2;
//
// node.SetExpandPartRectangle(bounds);
// }
/// <summary>
/// Gets whether the expand part of the node +/- is aligned to the left of the node in left-to-right layout.
/// </summary>
/// <param name="node">Node to get expand part alignment for</param>
/// <returns>true if node expand part is aligned to the left in left-to-right layout.</returns>
private bool ExpandPartAlignedNear(Node node)
{
return true; // If changed LayoutExpandPart needs to be updated as well
}
// private NodeCollection GetTopLevelNodes()
// {
// return m_Tree.Nodes;
// }
private int NodeLevelOffset
{
get {return 10;}
}
#endregion
}
}

Some files were not shown because too many files have changed in this diff Show More